pub struct SlideContent {Show 29 fields
pub title: String,
pub content: Vec<String>,
pub bullets: Vec<BulletPoint>,
pub bullet_style: BulletStyle,
pub title_size: Option<u32>,
pub content_size: Option<u32>,
pub title_bold: bool,
pub content_bold: bool,
pub title_italic: bool,
pub content_italic: bool,
pub title_underline: bool,
pub content_underline: bool,
pub title_color: Option<String>,
pub content_color: Option<String>,
pub has_table: bool,
pub has_chart: bool,
pub has_image: bool,
pub layout: SlideLayout,
pub transition: TransitionType,
pub table: Option<Table>,
pub shapes: Vec<Shape>,
pub images: Vec<Image>,
pub notes: Option<String>,
pub connectors: Vec<Connector>,
pub videos: Vec<Video>,
pub audios: Vec<Audio>,
pub charts: Vec<Chart>,
pub code_blocks: Vec<CodeBlock>,
pub ink_annotations: Option<InkAnnotations>,
}Expand description
Slide content for more complex presentations
Fields§
§title: String§content: Vec<String>§bullets: Vec<BulletPoint>Rich bullet points with styles and levels
bullet_style: BulletStyleDefault bullet style for this slide
title_size: Option<u32>§content_size: Option<u32>§title_bold: bool§content_bold: bool§title_italic: bool§content_italic: bool§title_underline: bool§content_underline: bool§title_color: Option<String>§content_color: Option<String>§has_table: bool§has_chart: bool§has_image: bool§layout: SlideLayout§transition: TransitionType§table: Option<Table>§shapes: Vec<Shape>§images: Vec<Image>§notes: Option<String>Speaker notes for the slide
connectors: Vec<Connector>Connectors between shapes
videos: Vec<Video>Videos embedded in slide
audios: Vec<Audio>Audio files embedded in slide
charts: Vec<Chart>Charts embedded in slide
code_blocks: Vec<CodeBlock>Code blocks with syntax highlighting
ink_annotations: Option<InkAnnotations>Ink annotations on the slide
Implementations§
Source§impl SlideContent
impl SlideContent
Sourcepub fn new(title: &str) -> Self
pub fn new(title: &str) -> Self
Examples found in repository?
56fn create_simple_table_example() -> Result<(), Box<dyn std::error::Error>> {
57 let table = Table::from_data(
58 vec![
59 vec!["Name", "Age"],
60 vec!["Alice", "30"],
61 vec!["Bob", "25"],
62 ],
63 vec![2000000, 2000000],
64 500000,
65 1500000,
66 );
67
68 let slides = vec![
69 SlideContent::new("Simple 2x2 Table")
70 .add_bullet("Table with basic structure")
71 .add_bullet("Headers and data rows"),
72 SlideContent::new("Table Data")
73 .table(table),
74 ];
75
76 let pptx_data = create_pptx_with_content("Simple Table", slides)?;
77 fs::write("examples/output/simple_table.pptx", pptx_data)?;
78 Ok(())
79}
80
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}More examples
49fn create_large_title_example() -> Result<(), Box<dyn std::error::Error>> {
50 let slides = vec![
51 SlideContent::new("Large Title Slide")
52 .title_size(60) // 60pt title
53 .content_size(16) // 16pt content
54 .add_bullet("Small bullet point 1")
55 .add_bullet("Small bullet point 2")
56 .add_bullet("Small bullet point 3"),
57 SlideContent::new("Regular Formatting")
58 .add_bullet("Default 44pt title")
59 .add_bullet("Default 28pt content")
60 .add_bullet("Standard formatting"),
61 ];
62
63 let pptx_data = create_pptx_with_content("Large Title Example", slides)?;
64 fs::write("examples/output/large_title.pptx", pptx_data)?;
65 Ok(())
66}
67
68fn create_bold_content_example() -> Result<(), Box<dyn std::error::Error>> {
69 let slides = vec![
70 SlideContent::new("Bold Content Slide")
71 .title_bold(true)
72 .content_bold(true) // Make bullets bold
73 .add_bullet("Bold bullet point 1")
74 .add_bullet("Bold bullet point 2")
75 .add_bullet("Bold bullet point 3"),
76 SlideContent::new("Regular Content")
77 .title_bold(true)
78 .content_bold(false) // Regular bullets
79 .add_bullet("Regular bullet point 1")
80 .add_bullet("Regular bullet point 2"),
81 ];
82
83 let pptx_data = create_pptx_with_content("Bold Content Example", slides)?;
84 fs::write("examples/output/bold_content.pptx", pptx_data)?;
85 Ok(())
86}
87
88fn create_mixed_formatting_example() -> Result<(), Box<dyn std::error::Error>> {
89 let slides = vec![
90 SlideContent::new("Title Slide")
91 .title_size(52)
92 .title_bold(true)
93 .content_size(24)
94 .content_bold(false)
95 .add_bullet("Large content text")
96 .add_bullet("Still readable")
97 .add_bullet("Professional look"),
98 SlideContent::new("Compact Slide")
99 .title_size(36)
100 .title_bold(false)
101 .content_size(18)
102 .content_bold(true)
103 .add_bullet("Smaller title")
104 .add_bullet("Bold content")
105 .add_bullet("Tight spacing"),
106 SlideContent::new("Summary")
107 .title_size(48)
108 .title_bold(true)
109 .content_size(32)
110 .content_bold(true)
111 .add_bullet("Large bold text")
112 .add_bullet("High impact")
113 .add_bullet("Great for emphasis"),
114 ];
115
116 let pptx_data = create_pptx_with_content("Mixed Formatting Example", slides)?;
117 fs::write("examples/output/mixed_formatting.pptx", pptx_data)?;
118 Ok(())
119}3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title
6 SlideContent::new("Table Examples")
7 .add_bullet("Demonstrating table rendering in PPTX"),
8
9 // Slide 2: Simple 2x3 table
10 SlideContent::new("Employee Data")
11 .table(create_employee_table()),
12
13 // Slide 3: Styled table with colors
14 SlideContent::new("Sales Summary")
15 .table(create_sales_table()),
16
17 // Slide 4: Data table
18 SlideContent::new("Quarterly Results")
19 .table(create_quarterly_table()),
20 ];
21
22 let pptx_data = create_pptx_with_content("Table Demo", slides)?;
23 std::fs::write("table_demo.pptx", pptx_data)?;
24 println!("✓ Created table_demo.pptx with 4 slides containing tables");
25
26 Ok(())
27}53fn create_italic_underline_example() -> Result<(), Box<dyn std::error::Error>> {
54 let slides = vec![
55 SlideContent::new("Italic Text")
56 .title_italic(true)
57 .add_bullet("This is italic content")
58 .add_bullet("More italic text here"),
59 SlideContent::new("Underlined Text")
60 .title_underline(true)
61 .content_underline(true)
62 .add_bullet("Underlined bullet point 1")
63 .add_bullet("Underlined bullet point 2"),
64 SlideContent::new("Combined Effects")
65 .title_italic(true)
66 .title_underline(true)
67 .content_italic(true)
68 .add_bullet("Italic and underlined content")
69 .add_bullet("Multiple effects combined"),
70 ];
71
72 let pptx_data = create_pptx_with_content("Italic and Underline", slides)?;
73 fs::write("examples/output/italic_underline.pptx", pptx_data)?;
74 Ok(())
75}
76
77fn create_colored_text_example() -> Result<(), Box<dyn std::error::Error>> {
78 let slides = vec![
79 SlideContent::new("Red Title")
80 .title_color("FF0000")
81 .add_bullet("Red title text")
82 .add_bullet("Regular content"),
83 SlideContent::new("Blue Content")
84 .content_color("0000FF")
85 .add_bullet("Blue bullet point 1")
86 .add_bullet("Blue bullet point 2")
87 .add_bullet("Blue bullet point 3"),
88 SlideContent::new("Green Title & Content")
89 .title_color("00AA00")
90 .content_color("00AA00")
91 .add_bullet("Green title and content")
92 .add_bullet("All text is green"),
93 SlideContent::new("Purple Accent")
94 .title_color("9933FF")
95 .add_bullet("Purple title")
96 .add_bullet("Regular content"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Colored Text", slides)?;
100 fs::write("examples/output/colored_text.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}50fn create_text_formatting_example() -> Result<(), Box<dyn std::error::Error>> {
51 let slides = vec![
52 SlideContent::new("Text Formatting Examples")
53 .add_bullet("Bold text demonstration")
54 .add_bullet("Italic text demonstration")
55 .add_bullet("Underlined text demonstration")
56 .add_bullet("Colored text demonstration"),
57 SlideContent::new("Font Sizes")
58 .add_bullet("Small text (12pt)")
59 .add_bullet("Normal text (18pt)")
60 .add_bullet("Large text (24pt)")
61 .add_bullet("Extra large text (32pt)"),
62 SlideContent::new("Combined Formatting")
63 .add_bullet("Bold and italic together")
64 .add_bullet("Colored and underlined text")
65 .add_bullet("Large bold red text")
66 .add_bullet("Small italic blue text"),
67 ];
68
69 let pptx_data = create_pptx_with_content("Text Formatting", slides)?;
70 fs::write("examples/output/text_formatting.pptx", pptx_data)?;
71 Ok(())
72}
73
74fn create_shapes_example() -> Result<(), Box<dyn std::error::Error>> {
75 let slides = vec![
76 SlideContent::new("Shape Types")
77 .add_bullet("Rectangle - basic rectangular shape")
78 .add_bullet("Circle - round elliptical shape")
79 .add_bullet("Triangle - three-sided polygon")
80 .add_bullet("Diamond - rotated square")
81 .add_bullet("Arrow - directional indicator")
82 .add_bullet("Star - five-pointed star")
83 .add_bullet("Hexagon - six-sided polygon"),
84 SlideContent::new("Shape Properties")
85 .add_bullet("Fill colors - solid color fills")
86 .add_bullet("Transparency - adjustable opacity")
87 .add_bullet("Borders - customizable lines")
88 .add_bullet("Text - add text inside shapes")
89 .add_bullet("Positioning - precise placement")
90 .add_bullet("Sizing - flexible dimensions"),
91 SlideContent::new("Shape Examples")
92 .add_bullet("Rectangle: 2x1 inch blue box")
93 .add_bullet("Circle: 1 inch red circle")
94 .add_bullet("Triangle: green triangle with border")
95 .add_bullet("Diamond: yellow diamond with text")
96 .add_bullet("Arrow: orange arrow pointing right"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Shape Demonstrations", slides)?;
100 fs::write("examples/output/shapes_demo.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_tables_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Table Basics")
107 .add_bullet("Tables organize data in rows and columns")
108 .add_bullet("Headers can be formatted differently")
109 .add_bullet("Cells can have background colors")
110 .add_bullet("Text can be bold or styled")
111 .add_bullet("Column widths are customizable"),
112 SlideContent::new("Sales Data Example")
113 .add_bullet("Q1 2025: $2.5M revenue")
114 .add_bullet("Q2 2025: $3.1M revenue")
115 .add_bullet("Q3 2025: $3.8M revenue")
116 .add_bullet("Q4 2025: $4.2M revenue (projected)")
117 .add_bullet("Total: $13.6M annual revenue"),
118 SlideContent::new("Team Members")
119 .add_bullet("Alice Johnson - Engineering Lead")
120 .add_bullet("Bob Smith - Product Manager")
121 .add_bullet("Carol Davis - Design Lead")
122 .add_bullet("David Wilson - Marketing Manager")
123 .add_bullet("Eve Martinez - Operations"),
124 ];
125
126 let pptx_data = create_pptx_with_content("Table Examples", slides)?;
127 fs::write("examples/output/tables_demo.pptx", pptx_data)?;
128 Ok(())
129}3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title
6 SlideContent::new("Table Text Formatting Examples")
7 .add_bullet("Demonstrating rich text content in table cells"),
8
9 // Slide 2: Text formatting examples
10 SlideContent::new("Text Formatting in Tables")
11 .table(create_text_formatting_table()),
12
13 // Slide 3: Color examples
14 SlideContent::new("Text and Background Colors")
15 .table(create_color_table()),
16
17 // Slide 4: Font examples
18 SlideContent::new("Font Size and Family")
19 .table(create_font_table()),
20
21 // Slide 5: Combined formatting
22 SlideContent::new("Combined Formatting")
23 .table(create_combined_table()),
24 ];
25
26 let pptx_data = create_pptx_with_content("Table Text Formatting", slides)?;
27 std::fs::write("examples/output/table_text_formatting.pptx", pptx_data)?;
28 println!("✓ Created table_text_formatting.pptx with rich text formatting examples");
29
30 Ok(())
31}- examples/test_notes.rs
- examples/alignment_test.rs
- examples/chart_generation.rs
- examples/layout_demo.rs
- examples/repair_pptx.rs
- examples/advanced_charts.rs
- examples/read_pptx.rs
- examples/complex_pptx.rs
- examples/new_elements_demo.rs
- examples/edit_presentation.rs
- examples/new_features_demo.rs
- examples/read_presentation.rs
- examples/comprehensive_demo.rs
Sourcepub fn with_transition(self, transition: TransitionType) -> Self
pub fn with_transition(self, transition: TransitionType) -> Self
Set the slide transition
Sourcepub fn add_bullet(self, text: &str) -> Self
pub fn add_bullet(self, text: &str) -> Self
Add a bullet point with default style
Examples found in repository?
56fn create_simple_table_example() -> Result<(), Box<dyn std::error::Error>> {
57 let table = Table::from_data(
58 vec![
59 vec!["Name", "Age"],
60 vec!["Alice", "30"],
61 vec!["Bob", "25"],
62 ],
63 vec![2000000, 2000000],
64 500000,
65 1500000,
66 );
67
68 let slides = vec![
69 SlideContent::new("Simple 2x2 Table")
70 .add_bullet("Table with basic structure")
71 .add_bullet("Headers and data rows"),
72 SlideContent::new("Table Data")
73 .table(table),
74 ];
75
76 let pptx_data = create_pptx_with_content("Simple Table", slides)?;
77 fs::write("examples/output/simple_table.pptx", pptx_data)?;
78 Ok(())
79}
80
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}More examples
49fn create_large_title_example() -> Result<(), Box<dyn std::error::Error>> {
50 let slides = vec![
51 SlideContent::new("Large Title Slide")
52 .title_size(60) // 60pt title
53 .content_size(16) // 16pt content
54 .add_bullet("Small bullet point 1")
55 .add_bullet("Small bullet point 2")
56 .add_bullet("Small bullet point 3"),
57 SlideContent::new("Regular Formatting")
58 .add_bullet("Default 44pt title")
59 .add_bullet("Default 28pt content")
60 .add_bullet("Standard formatting"),
61 ];
62
63 let pptx_data = create_pptx_with_content("Large Title Example", slides)?;
64 fs::write("examples/output/large_title.pptx", pptx_data)?;
65 Ok(())
66}
67
68fn create_bold_content_example() -> Result<(), Box<dyn std::error::Error>> {
69 let slides = vec![
70 SlideContent::new("Bold Content Slide")
71 .title_bold(true)
72 .content_bold(true) // Make bullets bold
73 .add_bullet("Bold bullet point 1")
74 .add_bullet("Bold bullet point 2")
75 .add_bullet("Bold bullet point 3"),
76 SlideContent::new("Regular Content")
77 .title_bold(true)
78 .content_bold(false) // Regular bullets
79 .add_bullet("Regular bullet point 1")
80 .add_bullet("Regular bullet point 2"),
81 ];
82
83 let pptx_data = create_pptx_with_content("Bold Content Example", slides)?;
84 fs::write("examples/output/bold_content.pptx", pptx_data)?;
85 Ok(())
86}
87
88fn create_mixed_formatting_example() -> Result<(), Box<dyn std::error::Error>> {
89 let slides = vec![
90 SlideContent::new("Title Slide")
91 .title_size(52)
92 .title_bold(true)
93 .content_size(24)
94 .content_bold(false)
95 .add_bullet("Large content text")
96 .add_bullet("Still readable")
97 .add_bullet("Professional look"),
98 SlideContent::new("Compact Slide")
99 .title_size(36)
100 .title_bold(false)
101 .content_size(18)
102 .content_bold(true)
103 .add_bullet("Smaller title")
104 .add_bullet("Bold content")
105 .add_bullet("Tight spacing"),
106 SlideContent::new("Summary")
107 .title_size(48)
108 .title_bold(true)
109 .content_size(32)
110 .content_bold(true)
111 .add_bullet("Large bold text")
112 .add_bullet("High impact")
113 .add_bullet("Great for emphasis"),
114 ];
115
116 let pptx_data = create_pptx_with_content("Mixed Formatting Example", slides)?;
117 fs::write("examples/output/mixed_formatting.pptx", pptx_data)?;
118 Ok(())
119}3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title
6 SlideContent::new("Table Examples")
7 .add_bullet("Demonstrating table rendering in PPTX"),
8
9 // Slide 2: Simple 2x3 table
10 SlideContent::new("Employee Data")
11 .table(create_employee_table()),
12
13 // Slide 3: Styled table with colors
14 SlideContent::new("Sales Summary")
15 .table(create_sales_table()),
16
17 // Slide 4: Data table
18 SlideContent::new("Quarterly Results")
19 .table(create_quarterly_table()),
20 ];
21
22 let pptx_data = create_pptx_with_content("Table Demo", slides)?;
23 std::fs::write("table_demo.pptx", pptx_data)?;
24 println!("✓ Created table_demo.pptx with 4 slides containing tables");
25
26 Ok(())
27}53fn create_italic_underline_example() -> Result<(), Box<dyn std::error::Error>> {
54 let slides = vec![
55 SlideContent::new("Italic Text")
56 .title_italic(true)
57 .add_bullet("This is italic content")
58 .add_bullet("More italic text here"),
59 SlideContent::new("Underlined Text")
60 .title_underline(true)
61 .content_underline(true)
62 .add_bullet("Underlined bullet point 1")
63 .add_bullet("Underlined bullet point 2"),
64 SlideContent::new("Combined Effects")
65 .title_italic(true)
66 .title_underline(true)
67 .content_italic(true)
68 .add_bullet("Italic and underlined content")
69 .add_bullet("Multiple effects combined"),
70 ];
71
72 let pptx_data = create_pptx_with_content("Italic and Underline", slides)?;
73 fs::write("examples/output/italic_underline.pptx", pptx_data)?;
74 Ok(())
75}
76
77fn create_colored_text_example() -> Result<(), Box<dyn std::error::Error>> {
78 let slides = vec![
79 SlideContent::new("Red Title")
80 .title_color("FF0000")
81 .add_bullet("Red title text")
82 .add_bullet("Regular content"),
83 SlideContent::new("Blue Content")
84 .content_color("0000FF")
85 .add_bullet("Blue bullet point 1")
86 .add_bullet("Blue bullet point 2")
87 .add_bullet("Blue bullet point 3"),
88 SlideContent::new("Green Title & Content")
89 .title_color("00AA00")
90 .content_color("00AA00")
91 .add_bullet("Green title and content")
92 .add_bullet("All text is green"),
93 SlideContent::new("Purple Accent")
94 .title_color("9933FF")
95 .add_bullet("Purple title")
96 .add_bullet("Regular content"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Colored Text", slides)?;
100 fs::write("examples/output/colored_text.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}50fn create_text_formatting_example() -> Result<(), Box<dyn std::error::Error>> {
51 let slides = vec![
52 SlideContent::new("Text Formatting Examples")
53 .add_bullet("Bold text demonstration")
54 .add_bullet("Italic text demonstration")
55 .add_bullet("Underlined text demonstration")
56 .add_bullet("Colored text demonstration"),
57 SlideContent::new("Font Sizes")
58 .add_bullet("Small text (12pt)")
59 .add_bullet("Normal text (18pt)")
60 .add_bullet("Large text (24pt)")
61 .add_bullet("Extra large text (32pt)"),
62 SlideContent::new("Combined Formatting")
63 .add_bullet("Bold and italic together")
64 .add_bullet("Colored and underlined text")
65 .add_bullet("Large bold red text")
66 .add_bullet("Small italic blue text"),
67 ];
68
69 let pptx_data = create_pptx_with_content("Text Formatting", slides)?;
70 fs::write("examples/output/text_formatting.pptx", pptx_data)?;
71 Ok(())
72}
73
74fn create_shapes_example() -> Result<(), Box<dyn std::error::Error>> {
75 let slides = vec![
76 SlideContent::new("Shape Types")
77 .add_bullet("Rectangle - basic rectangular shape")
78 .add_bullet("Circle - round elliptical shape")
79 .add_bullet("Triangle - three-sided polygon")
80 .add_bullet("Diamond - rotated square")
81 .add_bullet("Arrow - directional indicator")
82 .add_bullet("Star - five-pointed star")
83 .add_bullet("Hexagon - six-sided polygon"),
84 SlideContent::new("Shape Properties")
85 .add_bullet("Fill colors - solid color fills")
86 .add_bullet("Transparency - adjustable opacity")
87 .add_bullet("Borders - customizable lines")
88 .add_bullet("Text - add text inside shapes")
89 .add_bullet("Positioning - precise placement")
90 .add_bullet("Sizing - flexible dimensions"),
91 SlideContent::new("Shape Examples")
92 .add_bullet("Rectangle: 2x1 inch blue box")
93 .add_bullet("Circle: 1 inch red circle")
94 .add_bullet("Triangle: green triangle with border")
95 .add_bullet("Diamond: yellow diamond with text")
96 .add_bullet("Arrow: orange arrow pointing right"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Shape Demonstrations", slides)?;
100 fs::write("examples/output/shapes_demo.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_tables_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Table Basics")
107 .add_bullet("Tables organize data in rows and columns")
108 .add_bullet("Headers can be formatted differently")
109 .add_bullet("Cells can have background colors")
110 .add_bullet("Text can be bold or styled")
111 .add_bullet("Column widths are customizable"),
112 SlideContent::new("Sales Data Example")
113 .add_bullet("Q1 2025: $2.5M revenue")
114 .add_bullet("Q2 2025: $3.1M revenue")
115 .add_bullet("Q3 2025: $3.8M revenue")
116 .add_bullet("Q4 2025: $4.2M revenue (projected)")
117 .add_bullet("Total: $13.6M annual revenue"),
118 SlideContent::new("Team Members")
119 .add_bullet("Alice Johnson - Engineering Lead")
120 .add_bullet("Bob Smith - Product Manager")
121 .add_bullet("Carol Davis - Design Lead")
122 .add_bullet("David Wilson - Marketing Manager")
123 .add_bullet("Eve Martinez - Operations"),
124 ];
125
126 let pptx_data = create_pptx_with_content("Table Examples", slides)?;
127 fs::write("examples/output/tables_demo.pptx", pptx_data)?;
128 Ok(())
129}3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title
6 SlideContent::new("Table Text Formatting Examples")
7 .add_bullet("Demonstrating rich text content in table cells"),
8
9 // Slide 2: Text formatting examples
10 SlideContent::new("Text Formatting in Tables")
11 .table(create_text_formatting_table()),
12
13 // Slide 3: Color examples
14 SlideContent::new("Text and Background Colors")
15 .table(create_color_table()),
16
17 // Slide 4: Font examples
18 SlideContent::new("Font Size and Family")
19 .table(create_font_table()),
20
21 // Slide 5: Combined formatting
22 SlideContent::new("Combined Formatting")
23 .table(create_combined_table()),
24 ];
25
26 let pptx_data = create_pptx_with_content("Table Text Formatting", slides)?;
27 std::fs::write("examples/output/table_text_formatting.pptx", pptx_data)?;
28 println!("✓ Created table_text_formatting.pptx with rich text formatting examples");
29
30 Ok(())
31}- examples/test_notes.rs
- examples/alignment_test.rs
- examples/chart_generation.rs
- examples/layout_demo.rs
- examples/repair_pptx.rs
- examples/advanced_charts.rs
- examples/read_pptx.rs
- examples/complex_pptx.rs
- examples/new_elements_demo.rs
- examples/edit_presentation.rs
- examples/new_features_demo.rs
- examples/read_presentation.rs
- examples/comprehensive_demo.rs
Sourcepub fn add_styled_bullet(self, text: &str, style: BulletStyle) -> Self
pub fn add_styled_bullet(self, text: &str, style: BulletStyle) -> Self
Add a bullet point with specific style
Examples found in repository?
13fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
14 // Create output directory
15 std::fs::create_dir_all("examples/output")?;
16
17 // 1. Bullet Styles Demo
18 println!("Creating bullet styles demo...");
19
20 // Numbered list slide
21 let numbered_slide = SlideContent::new("Numbered List")
22 .with_bullet_style(BulletStyle::Number)
23 .add_bullet("First step")
24 .add_bullet("Second step")
25 .add_bullet("Third step")
26 .add_bullet("Fourth step");
27
28 // Lettered list slide
29 let lettered_slide = SlideContent::new("Lettered List")
30 .add_lettered("Option A")
31 .add_lettered("Option B")
32 .add_lettered("Option C");
33
34 // Roman numerals slide
35 let roman_slide = SlideContent::new("Roman Numerals")
36 .with_bullet_style(BulletStyle::RomanUpper)
37 .add_bullet("Chapter I")
38 .add_bullet("Chapter II")
39 .add_bullet("Chapter III");
40
41 // Mixed bullets with sub-bullets
42 let mixed_slide = SlideContent::new("Mixed Bullets")
43 .add_bullet("Main point")
44 .add_sub_bullet("Supporting detail 1")
45 .add_sub_bullet("Supporting detail 2")
46 .add_bullet("Another main point")
47 .add_sub_bullet("More details");
48
49 // Custom bullet slide
50 let custom_slide = SlideContent::new("Custom Bullets")
51 .add_styled_bullet("Star bullet", BulletStyle::Custom('★'))
52 .add_styled_bullet("Arrow bullet", BulletStyle::Custom('→'))
53 .add_styled_bullet("Check bullet", BulletStyle::Custom('✓'))
54 .add_styled_bullet("Diamond bullet", BulletStyle::Custom('◆'));
55
56 let bullet_demo = pptx!("Bullet Styles Demo")
57 .title_slide("Bullet Styles - Demonstrating various list formats")
58 .content_slide(numbered_slide)
59 .content_slide(lettered_slide)
60 .content_slide(roman_slide)
61 .content_slide(mixed_slide)
62 .content_slide(custom_slide)
63 .build()?;
64
65 std::fs::write("examples/output/bullet_styles.pptx", bullet_demo)?;
66 println!(" ✓ Created examples/output/bullet_styles.pptx");
67
68 // 2. Text Formatting Demo
69 println!("Creating text formatting demo...");
70
71 let text_demo = pptx!("Text Formatting Demo")
72 .title_slide("Text Formatting - Strikethrough, highlight, subscript, superscript")
73 .slide("Text Styles", &[
74 "Normal text for comparison",
75 "This demonstrates various formatting options",
76 "Use TextFormat for rich text styling",
77 ])
78 .slide("Font Size Presets", &[
79 &format!("TITLE: {}pt - For main titles", font_sizes::TITLE),
80 &format!("SUBTITLE: {}pt - For subtitles", font_sizes::SUBTITLE),
81 &format!("HEADING: {}pt - For section headers", font_sizes::HEADING),
82 &format!("BODY: {}pt - For regular content", font_sizes::BODY),
83 &format!("SMALL: {}pt - For smaller text", font_sizes::SMALL),
84 &format!("CAPTION: {}pt - For captions", font_sizes::CAPTION),
85 ])
86 .slide("Text Effects", &[
87 "Strikethrough: For deleted text",
88 "Highlight: For emphasized text",
89 "Subscript: H₂O style formatting",
90 "Superscript: x² style formatting",
91 ])
92 .build()?;
93
94 std::fs::write("examples/output/text_formatting.pptx", text_demo)?;
95 println!(" ✓ Created examples/output/text_formatting.pptx");
96
97 // 3. Image from Base64 Demo
98 println!("Creating image demo...");
99
100 // 1x1 red PNG pixel in base64
101 let red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
102
103 // Create image from base64
104 let img = ImageBuilder::from_base64(red_pixel_base64, inches(2.0), inches(2.0), "PNG")
105 .position(inches(4.0), inches(3.0))
106 .build();
107
108 let image_slide = SlideContent::new("Image from Base64")
109 .add_bullet("Images can be loaded from base64 encoded data")
110 .add_bullet("Useful for embedding images without file access")
111 .add_bullet("Supports PNG, JPEG, GIF formats")
112 .add_image(img);
113
114 let image_demo = pptx!("Image Features Demo")
115 .title_slide("Image Features - Loading images from various sources")
116 .content_slide(image_slide)
117 .slide("Image Sources", &[
118 "Image::new(filename) - From file path",
119 "Image::from_base64(data) - From base64 string",
120 "Image::from_bytes(data) - From raw bytes",
121 "ImageBuilder for fluent API",
122 ])
123 .build()?;
124
125 std::fs::write("examples/output/image_features.pptx", image_demo)?;
126 println!(" ✓ Created examples/output/image_features.pptx");
127
128 // 4. Theme Colors Demo
129 println!("Creating themes demo...");
130
131 let all_themes = themes::all();
132 let theme_info: Vec<String> = all_themes.iter().map(|t| {
133 format!("{}: Primary={}, Accent={}", t.name, t.primary, t.accent)
134 }).collect();
135
136 let themes_demo = pptx!("Theme Colors Demo")
137 .title_slide("Theme Colors - Predefined color palettes")
138 .slide("Available Themes", &theme_info.iter().map(|s| s.as_str()).collect::<Vec<_>>())
139 .slide("Color Constants", &[
140 &format!("Material Red: {}", colors::MATERIAL_RED),
141 &format!("Material Blue: {}", colors::MATERIAL_BLUE),
142 &format!("Material Green: {}", colors::MATERIAL_GREEN),
143 &format!("Carbon Blue 60: {}", colors::CARBON_BLUE_60),
144 &format!("Carbon Gray 100: {}", colors::CARBON_GRAY_100),
145 ])
146 .build()?;
147
148 std::fs::write("examples/output/themes_demo.pptx", themes_demo)?;
149 println!(" ✓ Created examples/output/themes_demo.pptx");
150
151 // 5. Complete Feature Showcase
152 println!("Creating complete feature showcase...");
153
154 let showcase = pptx!("ppt-rs v0.2.1 Features")
155 .title_slide("New Features in ppt-rs v0.2.1")
156 .slide("Bullet Formatting", &[
157 "BulletStyle::Number - 1, 2, 3...",
158 "BulletStyle::LetterLower/Upper - a, b, c / A, B, C",
159 "BulletStyle::RomanLower/Upper - i, ii, iii / I, II, III",
160 "BulletStyle::Custom(char) - Any custom character",
161 "Sub-bullets with indentation",
162 ])
163 .slide("Text Enhancements", &[
164 "TextFormat::strikethrough() - Strike through text",
165 "TextFormat::highlight(color) - Background highlight",
166 "TextFormat::subscript() - H₂O style",
167 "TextFormat::superscript() - x² style",
168 "font_sizes module with presets",
169 ])
170 .slide("Image Loading", &[
171 "Image::from_base64() - Base64 encoded images",
172 "Image::from_bytes() - Raw byte arrays",
173 "ImageSource enum for flexible handling",
174 "Built-in base64 decoder",
175 ])
176 .slide("Templates", &[
177 "templates::business_proposal()",
178 "templates::status_report()",
179 "templates::training_material()",
180 "templates::technical_doc()",
181 "templates::simple()",
182 ])
183 .slide("Themes & Colors", &[
184 "themes::CORPORATE, MODERN, VIBRANT, DARK",
185 "themes::NATURE, TECH, CARBON",
186 "colors module with Material Design colors",
187 "colors module with IBM Carbon colors",
188 ])
189 .build()?;
190
191 std::fs::write("examples/output/feature_showcase.pptx", showcase)?;
192 println!(" ✓ Created examples/output/feature_showcase.pptx");
193
194 println!("\n✅ All demos created successfully!");
195 println!(" Check examples/output/ for the generated files.");
196
197 Ok(())
198}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn add_numbered(self, text: &str) -> Self
pub fn add_numbered(self, text: &str) -> Self
Add a numbered item (shorthand for add_styled_bullet with Number)
Examples found in repository?
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn add_lettered(self, text: &str) -> Self
pub fn add_lettered(self, text: &str) -> Self
Add a lettered item (shorthand for add_styled_bullet with LetterLower)
Examples found in repository?
13fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
14 // Create output directory
15 std::fs::create_dir_all("examples/output")?;
16
17 // 1. Bullet Styles Demo
18 println!("Creating bullet styles demo...");
19
20 // Numbered list slide
21 let numbered_slide = SlideContent::new("Numbered List")
22 .with_bullet_style(BulletStyle::Number)
23 .add_bullet("First step")
24 .add_bullet("Second step")
25 .add_bullet("Third step")
26 .add_bullet("Fourth step");
27
28 // Lettered list slide
29 let lettered_slide = SlideContent::new("Lettered List")
30 .add_lettered("Option A")
31 .add_lettered("Option B")
32 .add_lettered("Option C");
33
34 // Roman numerals slide
35 let roman_slide = SlideContent::new("Roman Numerals")
36 .with_bullet_style(BulletStyle::RomanUpper)
37 .add_bullet("Chapter I")
38 .add_bullet("Chapter II")
39 .add_bullet("Chapter III");
40
41 // Mixed bullets with sub-bullets
42 let mixed_slide = SlideContent::new("Mixed Bullets")
43 .add_bullet("Main point")
44 .add_sub_bullet("Supporting detail 1")
45 .add_sub_bullet("Supporting detail 2")
46 .add_bullet("Another main point")
47 .add_sub_bullet("More details");
48
49 // Custom bullet slide
50 let custom_slide = SlideContent::new("Custom Bullets")
51 .add_styled_bullet("Star bullet", BulletStyle::Custom('★'))
52 .add_styled_bullet("Arrow bullet", BulletStyle::Custom('→'))
53 .add_styled_bullet("Check bullet", BulletStyle::Custom('✓'))
54 .add_styled_bullet("Diamond bullet", BulletStyle::Custom('◆'));
55
56 let bullet_demo = pptx!("Bullet Styles Demo")
57 .title_slide("Bullet Styles - Demonstrating various list formats")
58 .content_slide(numbered_slide)
59 .content_slide(lettered_slide)
60 .content_slide(roman_slide)
61 .content_slide(mixed_slide)
62 .content_slide(custom_slide)
63 .build()?;
64
65 std::fs::write("examples/output/bullet_styles.pptx", bullet_demo)?;
66 println!(" ✓ Created examples/output/bullet_styles.pptx");
67
68 // 2. Text Formatting Demo
69 println!("Creating text formatting demo...");
70
71 let text_demo = pptx!("Text Formatting Demo")
72 .title_slide("Text Formatting - Strikethrough, highlight, subscript, superscript")
73 .slide("Text Styles", &[
74 "Normal text for comparison",
75 "This demonstrates various formatting options",
76 "Use TextFormat for rich text styling",
77 ])
78 .slide("Font Size Presets", &[
79 &format!("TITLE: {}pt - For main titles", font_sizes::TITLE),
80 &format!("SUBTITLE: {}pt - For subtitles", font_sizes::SUBTITLE),
81 &format!("HEADING: {}pt - For section headers", font_sizes::HEADING),
82 &format!("BODY: {}pt - For regular content", font_sizes::BODY),
83 &format!("SMALL: {}pt - For smaller text", font_sizes::SMALL),
84 &format!("CAPTION: {}pt - For captions", font_sizes::CAPTION),
85 ])
86 .slide("Text Effects", &[
87 "Strikethrough: For deleted text",
88 "Highlight: For emphasized text",
89 "Subscript: H₂O style formatting",
90 "Superscript: x² style formatting",
91 ])
92 .build()?;
93
94 std::fs::write("examples/output/text_formatting.pptx", text_demo)?;
95 println!(" ✓ Created examples/output/text_formatting.pptx");
96
97 // 3. Image from Base64 Demo
98 println!("Creating image demo...");
99
100 // 1x1 red PNG pixel in base64
101 let red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
102
103 // Create image from base64
104 let img = ImageBuilder::from_base64(red_pixel_base64, inches(2.0), inches(2.0), "PNG")
105 .position(inches(4.0), inches(3.0))
106 .build();
107
108 let image_slide = SlideContent::new("Image from Base64")
109 .add_bullet("Images can be loaded from base64 encoded data")
110 .add_bullet("Useful for embedding images without file access")
111 .add_bullet("Supports PNG, JPEG, GIF formats")
112 .add_image(img);
113
114 let image_demo = pptx!("Image Features Demo")
115 .title_slide("Image Features - Loading images from various sources")
116 .content_slide(image_slide)
117 .slide("Image Sources", &[
118 "Image::new(filename) - From file path",
119 "Image::from_base64(data) - From base64 string",
120 "Image::from_bytes(data) - From raw bytes",
121 "ImageBuilder for fluent API",
122 ])
123 .build()?;
124
125 std::fs::write("examples/output/image_features.pptx", image_demo)?;
126 println!(" ✓ Created examples/output/image_features.pptx");
127
128 // 4. Theme Colors Demo
129 println!("Creating themes demo...");
130
131 let all_themes = themes::all();
132 let theme_info: Vec<String> = all_themes.iter().map(|t| {
133 format!("{}: Primary={}, Accent={}", t.name, t.primary, t.accent)
134 }).collect();
135
136 let themes_demo = pptx!("Theme Colors Demo")
137 .title_slide("Theme Colors - Predefined color palettes")
138 .slide("Available Themes", &theme_info.iter().map(|s| s.as_str()).collect::<Vec<_>>())
139 .slide("Color Constants", &[
140 &format!("Material Red: {}", colors::MATERIAL_RED),
141 &format!("Material Blue: {}", colors::MATERIAL_BLUE),
142 &format!("Material Green: {}", colors::MATERIAL_GREEN),
143 &format!("Carbon Blue 60: {}", colors::CARBON_BLUE_60),
144 &format!("Carbon Gray 100: {}", colors::CARBON_GRAY_100),
145 ])
146 .build()?;
147
148 std::fs::write("examples/output/themes_demo.pptx", themes_demo)?;
149 println!(" ✓ Created examples/output/themes_demo.pptx");
150
151 // 5. Complete Feature Showcase
152 println!("Creating complete feature showcase...");
153
154 let showcase = pptx!("ppt-rs v0.2.1 Features")
155 .title_slide("New Features in ppt-rs v0.2.1")
156 .slide("Bullet Formatting", &[
157 "BulletStyle::Number - 1, 2, 3...",
158 "BulletStyle::LetterLower/Upper - a, b, c / A, B, C",
159 "BulletStyle::RomanLower/Upper - i, ii, iii / I, II, III",
160 "BulletStyle::Custom(char) - Any custom character",
161 "Sub-bullets with indentation",
162 ])
163 .slide("Text Enhancements", &[
164 "TextFormat::strikethrough() - Strike through text",
165 "TextFormat::highlight(color) - Background highlight",
166 "TextFormat::subscript() - H₂O style",
167 "TextFormat::superscript() - x² style",
168 "font_sizes module with presets",
169 ])
170 .slide("Image Loading", &[
171 "Image::from_base64() - Base64 encoded images",
172 "Image::from_bytes() - Raw byte arrays",
173 "ImageSource enum for flexible handling",
174 "Built-in base64 decoder",
175 ])
176 .slide("Templates", &[
177 "templates::business_proposal()",
178 "templates::status_report()",
179 "templates::training_material()",
180 "templates::technical_doc()",
181 "templates::simple()",
182 ])
183 .slide("Themes & Colors", &[
184 "themes::CORPORATE, MODERN, VIBRANT, DARK",
185 "themes::NATURE, TECH, CARBON",
186 "colors module with Material Design colors",
187 "colors module with IBM Carbon colors",
188 ])
189 .build()?;
190
191 std::fs::write("examples/output/feature_showcase.pptx", showcase)?;
192 println!(" ✓ Created examples/output/feature_showcase.pptx");
193
194 println!("\n✅ All demos created successfully!");
195 println!(" Check examples/output/ for the generated files.");
196
197 Ok(())
198}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn add_sub_bullet(self, text: &str) -> Self
pub fn add_sub_bullet(self, text: &str) -> Self
Add a sub-bullet (indented)
Examples found in repository?
13fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
14 // Create output directory
15 std::fs::create_dir_all("examples/output")?;
16
17 // 1. Bullet Styles Demo
18 println!("Creating bullet styles demo...");
19
20 // Numbered list slide
21 let numbered_slide = SlideContent::new("Numbered List")
22 .with_bullet_style(BulletStyle::Number)
23 .add_bullet("First step")
24 .add_bullet("Second step")
25 .add_bullet("Third step")
26 .add_bullet("Fourth step");
27
28 // Lettered list slide
29 let lettered_slide = SlideContent::new("Lettered List")
30 .add_lettered("Option A")
31 .add_lettered("Option B")
32 .add_lettered("Option C");
33
34 // Roman numerals slide
35 let roman_slide = SlideContent::new("Roman Numerals")
36 .with_bullet_style(BulletStyle::RomanUpper)
37 .add_bullet("Chapter I")
38 .add_bullet("Chapter II")
39 .add_bullet("Chapter III");
40
41 // Mixed bullets with sub-bullets
42 let mixed_slide = SlideContent::new("Mixed Bullets")
43 .add_bullet("Main point")
44 .add_sub_bullet("Supporting detail 1")
45 .add_sub_bullet("Supporting detail 2")
46 .add_bullet("Another main point")
47 .add_sub_bullet("More details");
48
49 // Custom bullet slide
50 let custom_slide = SlideContent::new("Custom Bullets")
51 .add_styled_bullet("Star bullet", BulletStyle::Custom('★'))
52 .add_styled_bullet("Arrow bullet", BulletStyle::Custom('→'))
53 .add_styled_bullet("Check bullet", BulletStyle::Custom('✓'))
54 .add_styled_bullet("Diamond bullet", BulletStyle::Custom('◆'));
55
56 let bullet_demo = pptx!("Bullet Styles Demo")
57 .title_slide("Bullet Styles - Demonstrating various list formats")
58 .content_slide(numbered_slide)
59 .content_slide(lettered_slide)
60 .content_slide(roman_slide)
61 .content_slide(mixed_slide)
62 .content_slide(custom_slide)
63 .build()?;
64
65 std::fs::write("examples/output/bullet_styles.pptx", bullet_demo)?;
66 println!(" ✓ Created examples/output/bullet_styles.pptx");
67
68 // 2. Text Formatting Demo
69 println!("Creating text formatting demo...");
70
71 let text_demo = pptx!("Text Formatting Demo")
72 .title_slide("Text Formatting - Strikethrough, highlight, subscript, superscript")
73 .slide("Text Styles", &[
74 "Normal text for comparison",
75 "This demonstrates various formatting options",
76 "Use TextFormat for rich text styling",
77 ])
78 .slide("Font Size Presets", &[
79 &format!("TITLE: {}pt - For main titles", font_sizes::TITLE),
80 &format!("SUBTITLE: {}pt - For subtitles", font_sizes::SUBTITLE),
81 &format!("HEADING: {}pt - For section headers", font_sizes::HEADING),
82 &format!("BODY: {}pt - For regular content", font_sizes::BODY),
83 &format!("SMALL: {}pt - For smaller text", font_sizes::SMALL),
84 &format!("CAPTION: {}pt - For captions", font_sizes::CAPTION),
85 ])
86 .slide("Text Effects", &[
87 "Strikethrough: For deleted text",
88 "Highlight: For emphasized text",
89 "Subscript: H₂O style formatting",
90 "Superscript: x² style formatting",
91 ])
92 .build()?;
93
94 std::fs::write("examples/output/text_formatting.pptx", text_demo)?;
95 println!(" ✓ Created examples/output/text_formatting.pptx");
96
97 // 3. Image from Base64 Demo
98 println!("Creating image demo...");
99
100 // 1x1 red PNG pixel in base64
101 let red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
102
103 // Create image from base64
104 let img = ImageBuilder::from_base64(red_pixel_base64, inches(2.0), inches(2.0), "PNG")
105 .position(inches(4.0), inches(3.0))
106 .build();
107
108 let image_slide = SlideContent::new("Image from Base64")
109 .add_bullet("Images can be loaded from base64 encoded data")
110 .add_bullet("Useful for embedding images without file access")
111 .add_bullet("Supports PNG, JPEG, GIF formats")
112 .add_image(img);
113
114 let image_demo = pptx!("Image Features Demo")
115 .title_slide("Image Features - Loading images from various sources")
116 .content_slide(image_slide)
117 .slide("Image Sources", &[
118 "Image::new(filename) - From file path",
119 "Image::from_base64(data) - From base64 string",
120 "Image::from_bytes(data) - From raw bytes",
121 "ImageBuilder for fluent API",
122 ])
123 .build()?;
124
125 std::fs::write("examples/output/image_features.pptx", image_demo)?;
126 println!(" ✓ Created examples/output/image_features.pptx");
127
128 // 4. Theme Colors Demo
129 println!("Creating themes demo...");
130
131 let all_themes = themes::all();
132 let theme_info: Vec<String> = all_themes.iter().map(|t| {
133 format!("{}: Primary={}, Accent={}", t.name, t.primary, t.accent)
134 }).collect();
135
136 let themes_demo = pptx!("Theme Colors Demo")
137 .title_slide("Theme Colors - Predefined color palettes")
138 .slide("Available Themes", &theme_info.iter().map(|s| s.as_str()).collect::<Vec<_>>())
139 .slide("Color Constants", &[
140 &format!("Material Red: {}", colors::MATERIAL_RED),
141 &format!("Material Blue: {}", colors::MATERIAL_BLUE),
142 &format!("Material Green: {}", colors::MATERIAL_GREEN),
143 &format!("Carbon Blue 60: {}", colors::CARBON_BLUE_60),
144 &format!("Carbon Gray 100: {}", colors::CARBON_GRAY_100),
145 ])
146 .build()?;
147
148 std::fs::write("examples/output/themes_demo.pptx", themes_demo)?;
149 println!(" ✓ Created examples/output/themes_demo.pptx");
150
151 // 5. Complete Feature Showcase
152 println!("Creating complete feature showcase...");
153
154 let showcase = pptx!("ppt-rs v0.2.1 Features")
155 .title_slide("New Features in ppt-rs v0.2.1")
156 .slide("Bullet Formatting", &[
157 "BulletStyle::Number - 1, 2, 3...",
158 "BulletStyle::LetterLower/Upper - a, b, c / A, B, C",
159 "BulletStyle::RomanLower/Upper - i, ii, iii / I, II, III",
160 "BulletStyle::Custom(char) - Any custom character",
161 "Sub-bullets with indentation",
162 ])
163 .slide("Text Enhancements", &[
164 "TextFormat::strikethrough() - Strike through text",
165 "TextFormat::highlight(color) - Background highlight",
166 "TextFormat::subscript() - H₂O style",
167 "TextFormat::superscript() - x² style",
168 "font_sizes module with presets",
169 ])
170 .slide("Image Loading", &[
171 "Image::from_base64() - Base64 encoded images",
172 "Image::from_bytes() - Raw byte arrays",
173 "ImageSource enum for flexible handling",
174 "Built-in base64 decoder",
175 ])
176 .slide("Templates", &[
177 "templates::business_proposal()",
178 "templates::status_report()",
179 "templates::training_material()",
180 "templates::technical_doc()",
181 "templates::simple()",
182 ])
183 .slide("Themes & Colors", &[
184 "themes::CORPORATE, MODERN, VIBRANT, DARK",
185 "themes::NATURE, TECH, CARBON",
186 "colors module with Material Design colors",
187 "colors module with IBM Carbon colors",
188 ])
189 .build()?;
190
191 std::fs::write("examples/output/feature_showcase.pptx", showcase)?;
192 println!(" ✓ Created examples/output/feature_showcase.pptx");
193
194 println!("\n✅ All demos created successfully!");
195 println!(" Check examples/output/ for the generated files.");
196
197 Ok(())
198}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn with_bullet_style(self, style: BulletStyle) -> Self
pub fn with_bullet_style(self, style: BulletStyle) -> Self
Set default bullet style for this slide
Examples found in repository?
13fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
14 // Create output directory
15 std::fs::create_dir_all("examples/output")?;
16
17 // 1. Bullet Styles Demo
18 println!("Creating bullet styles demo...");
19
20 // Numbered list slide
21 let numbered_slide = SlideContent::new("Numbered List")
22 .with_bullet_style(BulletStyle::Number)
23 .add_bullet("First step")
24 .add_bullet("Second step")
25 .add_bullet("Third step")
26 .add_bullet("Fourth step");
27
28 // Lettered list slide
29 let lettered_slide = SlideContent::new("Lettered List")
30 .add_lettered("Option A")
31 .add_lettered("Option B")
32 .add_lettered("Option C");
33
34 // Roman numerals slide
35 let roman_slide = SlideContent::new("Roman Numerals")
36 .with_bullet_style(BulletStyle::RomanUpper)
37 .add_bullet("Chapter I")
38 .add_bullet("Chapter II")
39 .add_bullet("Chapter III");
40
41 // Mixed bullets with sub-bullets
42 let mixed_slide = SlideContent::new("Mixed Bullets")
43 .add_bullet("Main point")
44 .add_sub_bullet("Supporting detail 1")
45 .add_sub_bullet("Supporting detail 2")
46 .add_bullet("Another main point")
47 .add_sub_bullet("More details");
48
49 // Custom bullet slide
50 let custom_slide = SlideContent::new("Custom Bullets")
51 .add_styled_bullet("Star bullet", BulletStyle::Custom('★'))
52 .add_styled_bullet("Arrow bullet", BulletStyle::Custom('→'))
53 .add_styled_bullet("Check bullet", BulletStyle::Custom('✓'))
54 .add_styled_bullet("Diamond bullet", BulletStyle::Custom('◆'));
55
56 let bullet_demo = pptx!("Bullet Styles Demo")
57 .title_slide("Bullet Styles - Demonstrating various list formats")
58 .content_slide(numbered_slide)
59 .content_slide(lettered_slide)
60 .content_slide(roman_slide)
61 .content_slide(mixed_slide)
62 .content_slide(custom_slide)
63 .build()?;
64
65 std::fs::write("examples/output/bullet_styles.pptx", bullet_demo)?;
66 println!(" ✓ Created examples/output/bullet_styles.pptx");
67
68 // 2. Text Formatting Demo
69 println!("Creating text formatting demo...");
70
71 let text_demo = pptx!("Text Formatting Demo")
72 .title_slide("Text Formatting - Strikethrough, highlight, subscript, superscript")
73 .slide("Text Styles", &[
74 "Normal text for comparison",
75 "This demonstrates various formatting options",
76 "Use TextFormat for rich text styling",
77 ])
78 .slide("Font Size Presets", &[
79 &format!("TITLE: {}pt - For main titles", font_sizes::TITLE),
80 &format!("SUBTITLE: {}pt - For subtitles", font_sizes::SUBTITLE),
81 &format!("HEADING: {}pt - For section headers", font_sizes::HEADING),
82 &format!("BODY: {}pt - For regular content", font_sizes::BODY),
83 &format!("SMALL: {}pt - For smaller text", font_sizes::SMALL),
84 &format!("CAPTION: {}pt - For captions", font_sizes::CAPTION),
85 ])
86 .slide("Text Effects", &[
87 "Strikethrough: For deleted text",
88 "Highlight: For emphasized text",
89 "Subscript: H₂O style formatting",
90 "Superscript: x² style formatting",
91 ])
92 .build()?;
93
94 std::fs::write("examples/output/text_formatting.pptx", text_demo)?;
95 println!(" ✓ Created examples/output/text_formatting.pptx");
96
97 // 3. Image from Base64 Demo
98 println!("Creating image demo...");
99
100 // 1x1 red PNG pixel in base64
101 let red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
102
103 // Create image from base64
104 let img = ImageBuilder::from_base64(red_pixel_base64, inches(2.0), inches(2.0), "PNG")
105 .position(inches(4.0), inches(3.0))
106 .build();
107
108 let image_slide = SlideContent::new("Image from Base64")
109 .add_bullet("Images can be loaded from base64 encoded data")
110 .add_bullet("Useful for embedding images without file access")
111 .add_bullet("Supports PNG, JPEG, GIF formats")
112 .add_image(img);
113
114 let image_demo = pptx!("Image Features Demo")
115 .title_slide("Image Features - Loading images from various sources")
116 .content_slide(image_slide)
117 .slide("Image Sources", &[
118 "Image::new(filename) - From file path",
119 "Image::from_base64(data) - From base64 string",
120 "Image::from_bytes(data) - From raw bytes",
121 "ImageBuilder for fluent API",
122 ])
123 .build()?;
124
125 std::fs::write("examples/output/image_features.pptx", image_demo)?;
126 println!(" ✓ Created examples/output/image_features.pptx");
127
128 // 4. Theme Colors Demo
129 println!("Creating themes demo...");
130
131 let all_themes = themes::all();
132 let theme_info: Vec<String> = all_themes.iter().map(|t| {
133 format!("{}: Primary={}, Accent={}", t.name, t.primary, t.accent)
134 }).collect();
135
136 let themes_demo = pptx!("Theme Colors Demo")
137 .title_slide("Theme Colors - Predefined color palettes")
138 .slide("Available Themes", &theme_info.iter().map(|s| s.as_str()).collect::<Vec<_>>())
139 .slide("Color Constants", &[
140 &format!("Material Red: {}", colors::MATERIAL_RED),
141 &format!("Material Blue: {}", colors::MATERIAL_BLUE),
142 &format!("Material Green: {}", colors::MATERIAL_GREEN),
143 &format!("Carbon Blue 60: {}", colors::CARBON_BLUE_60),
144 &format!("Carbon Gray 100: {}", colors::CARBON_GRAY_100),
145 ])
146 .build()?;
147
148 std::fs::write("examples/output/themes_demo.pptx", themes_demo)?;
149 println!(" ✓ Created examples/output/themes_demo.pptx");
150
151 // 5. Complete Feature Showcase
152 println!("Creating complete feature showcase...");
153
154 let showcase = pptx!("ppt-rs v0.2.1 Features")
155 .title_slide("New Features in ppt-rs v0.2.1")
156 .slide("Bullet Formatting", &[
157 "BulletStyle::Number - 1, 2, 3...",
158 "BulletStyle::LetterLower/Upper - a, b, c / A, B, C",
159 "BulletStyle::RomanLower/Upper - i, ii, iii / I, II, III",
160 "BulletStyle::Custom(char) - Any custom character",
161 "Sub-bullets with indentation",
162 ])
163 .slide("Text Enhancements", &[
164 "TextFormat::strikethrough() - Strike through text",
165 "TextFormat::highlight(color) - Background highlight",
166 "TextFormat::subscript() - H₂O style",
167 "TextFormat::superscript() - x² style",
168 "font_sizes module with presets",
169 ])
170 .slide("Image Loading", &[
171 "Image::from_base64() - Base64 encoded images",
172 "Image::from_bytes() - Raw byte arrays",
173 "ImageSource enum for flexible handling",
174 "Built-in base64 decoder",
175 ])
176 .slide("Templates", &[
177 "templates::business_proposal()",
178 "templates::status_report()",
179 "templates::training_material()",
180 "templates::technical_doc()",
181 "templates::simple()",
182 ])
183 .slide("Themes & Colors", &[
184 "themes::CORPORATE, MODERN, VIBRANT, DARK",
185 "themes::NATURE, TECH, CARBON",
186 "colors module with Material Design colors",
187 "colors module with IBM Carbon colors",
188 ])
189 .build()?;
190
191 std::fs::write("examples/output/feature_showcase.pptx", showcase)?;
192 println!(" ✓ Created examples/output/feature_showcase.pptx");
193
194 println!("\n✅ All demos created successfully!");
195 println!(" Check examples/output/ for the generated files.");
196
197 Ok(())
198}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn title_size(self, size: u32) -> Self
pub fn title_size(self, size: u32) -> Self
Examples found in repository?
49fn create_large_title_example() -> Result<(), Box<dyn std::error::Error>> {
50 let slides = vec![
51 SlideContent::new("Large Title Slide")
52 .title_size(60) // 60pt title
53 .content_size(16) // 16pt content
54 .add_bullet("Small bullet point 1")
55 .add_bullet("Small bullet point 2")
56 .add_bullet("Small bullet point 3"),
57 SlideContent::new("Regular Formatting")
58 .add_bullet("Default 44pt title")
59 .add_bullet("Default 28pt content")
60 .add_bullet("Standard formatting"),
61 ];
62
63 let pptx_data = create_pptx_with_content("Large Title Example", slides)?;
64 fs::write("examples/output/large_title.pptx", pptx_data)?;
65 Ok(())
66}
67
68fn create_bold_content_example() -> Result<(), Box<dyn std::error::Error>> {
69 let slides = vec![
70 SlideContent::new("Bold Content Slide")
71 .title_bold(true)
72 .content_bold(true) // Make bullets bold
73 .add_bullet("Bold bullet point 1")
74 .add_bullet("Bold bullet point 2")
75 .add_bullet("Bold bullet point 3"),
76 SlideContent::new("Regular Content")
77 .title_bold(true)
78 .content_bold(false) // Regular bullets
79 .add_bullet("Regular bullet point 1")
80 .add_bullet("Regular bullet point 2"),
81 ];
82
83 let pptx_data = create_pptx_with_content("Bold Content Example", slides)?;
84 fs::write("examples/output/bold_content.pptx", pptx_data)?;
85 Ok(())
86}
87
88fn create_mixed_formatting_example() -> Result<(), Box<dyn std::error::Error>> {
89 let slides = vec![
90 SlideContent::new("Title Slide")
91 .title_size(52)
92 .title_bold(true)
93 .content_size(24)
94 .content_bold(false)
95 .add_bullet("Large content text")
96 .add_bullet("Still readable")
97 .add_bullet("Professional look"),
98 SlideContent::new("Compact Slide")
99 .title_size(36)
100 .title_bold(false)
101 .content_size(18)
102 .content_bold(true)
103 .add_bullet("Smaller title")
104 .add_bullet("Bold content")
105 .add_bullet("Tight spacing"),
106 SlideContent::new("Summary")
107 .title_size(48)
108 .title_bold(true)
109 .content_size(32)
110 .content_bold(true)
111 .add_bullet("Large bold text")
112 .add_bullet("High impact")
113 .add_bullet("Great for emphasis"),
114 ];
115
116 let pptx_data = create_pptx_with_content("Mixed Formatting Example", slides)?;
117 fs::write("examples/output/mixed_formatting.pptx", pptx_data)?;
118 Ok(())
119}More examples
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 println!("Creating test presentation with speaker notes...");
8
9 let slides = vec![
10 SlideContent::new("Slide 1 - With Notes")
11 .layout(SlideLayout::CenteredTitle)
12 .title_size(54)
13 .title_bold(true)
14 .notes("This is a speaker note for slide 1. It should appear in presenter view."),
15
16 SlideContent::new("Slide 2 - Also With Notes")
17 .add_bullet("Bullet point 1")
18 .add_bullet("Bullet point 2")
19 .add_bullet("Bullet point 3")
20 .notes("Notes for slide 2 with bullet points."),
21
22 SlideContent::new("Slide 3 - No Notes")
23 .add_bullet("This slide has no notes"),
24
25 SlideContent::new("Slide 4 - More Notes")
26 .layout(SlideLayout::TwoColumn)
27 .add_bullet("Left 1")
28 .add_bullet("Left 2")
29 .add_bullet("Right 1")
30 .add_bullet("Right 2")
31 .notes("Two column layout with speaker notes."),
32 ];
33
34 let pptx_data = create_pptx_with_content("Test Notes", slides)?;
35 fs::write("test_notes.pptx", &pptx_data)?;
36 println!("Created test_notes.pptx ({} bytes)", pptx_data.len());
37 println!("\nOpen in PowerPoint and check presenter view for notes!");
38
39 Ok(())
40}104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}13fn main() -> Result<(), Box<dyn std::error::Error>> {
14 println!("=== Alignment Test: ppt-rs vs python-pptx ===\n");
15
16 // Create output directory
17 fs::create_dir_all("examples/output")?;
18
19 // Create slides matching the reference presentation structure
20 let slides = vec![
21 // Slide 1: Title Slide
22 SlideContent::new("Alignment Test Presentation")
23 .title_size(54)
24 .title_bold(true)
25 .title_color("003366"), // RGB(0, 51, 102)
26
27 // Slide 2: Content Slide
28 SlideContent::new("Shapes and Formatting")
29 .title_size(44)
30 .title_bold(true)
31 .title_color("003366")
32 .add_bullet("Text formatting (bold, colors, sizes)")
33 .add_bullet("Shape creation and positioning")
34 .add_bullet("Multiple slides and layouts"),
35 ];
36
37 // Generate PPTX
38 let pptx_data = create_pptx_with_content(
39 "Alignment Test Presentation",
40 slides,
41 )?;
42
43 // Write to file
44 let output_path = "examples/output/alignment_test_ppt_rs.pptx";
45 fs::write(output_path, pptx_data)?;
46
47 println!("✓ Created presentation: {output_path}");
48 println!(" - Title: Alignment Test Presentation");
49 println!(" - Slides: 2");
50 println!("\nNext steps:");
51 println!(" 1. Generate reference: python3 scripts/generate_reference.py");
52 println!(" 2. Compare files: python3 scripts/compare_pptx.py");
53
54 Ok(())
55}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}3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title Only
6 SlideContent::new("Welcome to Layout Demo")
7 .layout(SlideLayout::TitleOnly),
8
9 // Slide 2: Centered Title (good for cover slides)
10 SlideContent::new("Centered Title Slide")
11 .layout(SlideLayout::CenteredTitle)
12 .title_size(60)
13 .title_color("4F81BD"),
14
15 // Slide 3: Title and Content (standard layout)
16 SlideContent::new("Standard Layout")
17 .add_bullet("Point 1: Title at top")
18 .add_bullet("Point 2: Content below")
19 .add_bullet("Point 3: Most common layout")
20 .layout(SlideLayout::TitleAndContent),
21
22 // Slide 4: Title and Big Content
23 SlideContent::new("Big Content Area")
24 .add_bullet("More space for content")
25 .add_bullet("Smaller title area")
26 .add_bullet("Good for detailed slides")
27 .add_bullet("Maximizes content space")
28 .layout(SlideLayout::TitleAndBigContent),
29
30 // Slide 5: Two Column Layout
31 SlideContent::new("Two Column Layout")
32 .add_bullet("Left column content")
33 .add_bullet("Organized side by side")
34 .add_bullet("Great for comparisons")
35 .layout(SlideLayout::TwoColumn),
36
37 // Slide 6: Blank Slide
38 SlideContent::new("")
39 .layout(SlideLayout::Blank),
40
41 // Slide 7: Summary with different formatting
42 SlideContent::new("Summary")
43 .title_size(48)
44 .title_bold(true)
45 .title_color("C0504D")
46 .add_bullet("Layout types implemented:")
47 .add_bullet("• TitleOnly - Just title")
48 .add_bullet("• CenteredTitle - Title centered")
49 .add_bullet("• TitleAndContent - Standard")
50 .add_bullet("• TitleAndBigContent - Large content")
51 .add_bullet("• TwoColumn - Side by side")
52 .add_bullet("• Blank - Empty slide")
53 .content_size(20)
54 .layout(SlideLayout::TitleAndContent),
55 ];
56
57 let pptx_data = create_pptx_with_content("Layout Demo Presentation", slides)?;
58 std::fs::write("layout_demo.pptx", pptx_data)?;
59 println!("✓ Created layout_demo.pptx with 7 slides demonstrating different layouts");
60
61 Ok(())
62}Sourcepub fn content_size(self, size: u32) -> Self
pub fn content_size(self, size: u32) -> Self
Examples found in repository?
49fn create_large_title_example() -> Result<(), Box<dyn std::error::Error>> {
50 let slides = vec![
51 SlideContent::new("Large Title Slide")
52 .title_size(60) // 60pt title
53 .content_size(16) // 16pt content
54 .add_bullet("Small bullet point 1")
55 .add_bullet("Small bullet point 2")
56 .add_bullet("Small bullet point 3"),
57 SlideContent::new("Regular Formatting")
58 .add_bullet("Default 44pt title")
59 .add_bullet("Default 28pt content")
60 .add_bullet("Standard formatting"),
61 ];
62
63 let pptx_data = create_pptx_with_content("Large Title Example", slides)?;
64 fs::write("examples/output/large_title.pptx", pptx_data)?;
65 Ok(())
66}
67
68fn create_bold_content_example() -> Result<(), Box<dyn std::error::Error>> {
69 let slides = vec![
70 SlideContent::new("Bold Content Slide")
71 .title_bold(true)
72 .content_bold(true) // Make bullets bold
73 .add_bullet("Bold bullet point 1")
74 .add_bullet("Bold bullet point 2")
75 .add_bullet("Bold bullet point 3"),
76 SlideContent::new("Regular Content")
77 .title_bold(true)
78 .content_bold(false) // Regular bullets
79 .add_bullet("Regular bullet point 1")
80 .add_bullet("Regular bullet point 2"),
81 ];
82
83 let pptx_data = create_pptx_with_content("Bold Content Example", slides)?;
84 fs::write("examples/output/bold_content.pptx", pptx_data)?;
85 Ok(())
86}
87
88fn create_mixed_formatting_example() -> Result<(), Box<dyn std::error::Error>> {
89 let slides = vec![
90 SlideContent::new("Title Slide")
91 .title_size(52)
92 .title_bold(true)
93 .content_size(24)
94 .content_bold(false)
95 .add_bullet("Large content text")
96 .add_bullet("Still readable")
97 .add_bullet("Professional look"),
98 SlideContent::new("Compact Slide")
99 .title_size(36)
100 .title_bold(false)
101 .content_size(18)
102 .content_bold(true)
103 .add_bullet("Smaller title")
104 .add_bullet("Bold content")
105 .add_bullet("Tight spacing"),
106 SlideContent::new("Summary")
107 .title_size(48)
108 .title_bold(true)
109 .content_size(32)
110 .content_bold(true)
111 .add_bullet("Large bold text")
112 .add_bullet("High impact")
113 .add_bullet("Great for emphasis"),
114 ];
115
116 let pptx_data = create_pptx_with_content("Mixed Formatting Example", slides)?;
117 fs::write("examples/output/mixed_formatting.pptx", pptx_data)?;
118 Ok(())
119}More examples
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title Only
6 SlideContent::new("Welcome to Layout Demo")
7 .layout(SlideLayout::TitleOnly),
8
9 // Slide 2: Centered Title (good for cover slides)
10 SlideContent::new("Centered Title Slide")
11 .layout(SlideLayout::CenteredTitle)
12 .title_size(60)
13 .title_color("4F81BD"),
14
15 // Slide 3: Title and Content (standard layout)
16 SlideContent::new("Standard Layout")
17 .add_bullet("Point 1: Title at top")
18 .add_bullet("Point 2: Content below")
19 .add_bullet("Point 3: Most common layout")
20 .layout(SlideLayout::TitleAndContent),
21
22 // Slide 4: Title and Big Content
23 SlideContent::new("Big Content Area")
24 .add_bullet("More space for content")
25 .add_bullet("Smaller title area")
26 .add_bullet("Good for detailed slides")
27 .add_bullet("Maximizes content space")
28 .layout(SlideLayout::TitleAndBigContent),
29
30 // Slide 5: Two Column Layout
31 SlideContent::new("Two Column Layout")
32 .add_bullet("Left column content")
33 .add_bullet("Organized side by side")
34 .add_bullet("Great for comparisons")
35 .layout(SlideLayout::TwoColumn),
36
37 // Slide 6: Blank Slide
38 SlideContent::new("")
39 .layout(SlideLayout::Blank),
40
41 // Slide 7: Summary with different formatting
42 SlideContent::new("Summary")
43 .title_size(48)
44 .title_bold(true)
45 .title_color("C0504D")
46 .add_bullet("Layout types implemented:")
47 .add_bullet("• TitleOnly - Just title")
48 .add_bullet("• CenteredTitle - Title centered")
49 .add_bullet("• TitleAndContent - Standard")
50 .add_bullet("• TitleAndBigContent - Large content")
51 .add_bullet("• TwoColumn - Side by side")
52 .add_bullet("• Blank - Empty slide")
53 .content_size(20)
54 .layout(SlideLayout::TitleAndContent),
55 ];
56
57 let pptx_data = create_pptx_with_content("Layout Demo Presentation", slides)?;
58 std::fs::write("layout_demo.pptx", pptx_data)?;
59 println!("✓ Created layout_demo.pptx with 7 slides demonstrating different layouts");
60
61 Ok(())
62}68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn title_bold(self, bold: bool) -> Self
pub fn title_bold(self, bold: bool) -> Self
Examples found in repository?
68fn create_bold_content_example() -> Result<(), Box<dyn std::error::Error>> {
69 let slides = vec![
70 SlideContent::new("Bold Content Slide")
71 .title_bold(true)
72 .content_bold(true) // Make bullets bold
73 .add_bullet("Bold bullet point 1")
74 .add_bullet("Bold bullet point 2")
75 .add_bullet("Bold bullet point 3"),
76 SlideContent::new("Regular Content")
77 .title_bold(true)
78 .content_bold(false) // Regular bullets
79 .add_bullet("Regular bullet point 1")
80 .add_bullet("Regular bullet point 2"),
81 ];
82
83 let pptx_data = create_pptx_with_content("Bold Content Example", slides)?;
84 fs::write("examples/output/bold_content.pptx", pptx_data)?;
85 Ok(())
86}
87
88fn create_mixed_formatting_example() -> Result<(), Box<dyn std::error::Error>> {
89 let slides = vec![
90 SlideContent::new("Title Slide")
91 .title_size(52)
92 .title_bold(true)
93 .content_size(24)
94 .content_bold(false)
95 .add_bullet("Large content text")
96 .add_bullet("Still readable")
97 .add_bullet("Professional look"),
98 SlideContent::new("Compact Slide")
99 .title_size(36)
100 .title_bold(false)
101 .content_size(18)
102 .content_bold(true)
103 .add_bullet("Smaller title")
104 .add_bullet("Bold content")
105 .add_bullet("Tight spacing"),
106 SlideContent::new("Summary")
107 .title_size(48)
108 .title_bold(true)
109 .content_size(32)
110 .content_bold(true)
111 .add_bullet("Large bold text")
112 .add_bullet("High impact")
113 .add_bullet("Great for emphasis"),
114 ];
115
116 let pptx_data = create_pptx_with_content("Mixed Formatting Example", slides)?;
117 fs::write("examples/output/mixed_formatting.pptx", pptx_data)?;
118 Ok(())
119}More examples
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 println!("Creating test presentation with speaker notes...");
8
9 let slides = vec![
10 SlideContent::new("Slide 1 - With Notes")
11 .layout(SlideLayout::CenteredTitle)
12 .title_size(54)
13 .title_bold(true)
14 .notes("This is a speaker note for slide 1. It should appear in presenter view."),
15
16 SlideContent::new("Slide 2 - Also With Notes")
17 .add_bullet("Bullet point 1")
18 .add_bullet("Bullet point 2")
19 .add_bullet("Bullet point 3")
20 .notes("Notes for slide 2 with bullet points."),
21
22 SlideContent::new("Slide 3 - No Notes")
23 .add_bullet("This slide has no notes"),
24
25 SlideContent::new("Slide 4 - More Notes")
26 .layout(SlideLayout::TwoColumn)
27 .add_bullet("Left 1")
28 .add_bullet("Left 2")
29 .add_bullet("Right 1")
30 .add_bullet("Right 2")
31 .notes("Two column layout with speaker notes."),
32 ];
33
34 let pptx_data = create_pptx_with_content("Test Notes", slides)?;
35 fs::write("test_notes.pptx", &pptx_data)?;
36 println!("Created test_notes.pptx ({} bytes)", pptx_data.len());
37 println!("\nOpen in PowerPoint and check presenter view for notes!");
38
39 Ok(())
40}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}104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}13fn main() -> Result<(), Box<dyn std::error::Error>> {
14 println!("=== Alignment Test: ppt-rs vs python-pptx ===\n");
15
16 // Create output directory
17 fs::create_dir_all("examples/output")?;
18
19 // Create slides matching the reference presentation structure
20 let slides = vec![
21 // Slide 1: Title Slide
22 SlideContent::new("Alignment Test Presentation")
23 .title_size(54)
24 .title_bold(true)
25 .title_color("003366"), // RGB(0, 51, 102)
26
27 // Slide 2: Content Slide
28 SlideContent::new("Shapes and Formatting")
29 .title_size(44)
30 .title_bold(true)
31 .title_color("003366")
32 .add_bullet("Text formatting (bold, colors, sizes)")
33 .add_bullet("Shape creation and positioning")
34 .add_bullet("Multiple slides and layouts"),
35 ];
36
37 // Generate PPTX
38 let pptx_data = create_pptx_with_content(
39 "Alignment Test Presentation",
40 slides,
41 )?;
42
43 // Write to file
44 let output_path = "examples/output/alignment_test_ppt_rs.pptx";
45 fs::write(output_path, pptx_data)?;
46
47 println!("✓ Created presentation: {output_path}");
48 println!(" - Title: Alignment Test Presentation");
49 println!(" - Slides: 2");
50 println!("\nNext steps:");
51 println!(" 1. Generate reference: python3 scripts/generate_reference.py");
52 println!(" 2. Compare files: python3 scripts/compare_pptx.py");
53
54 Ok(())
55}3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title Only
6 SlideContent::new("Welcome to Layout Demo")
7 .layout(SlideLayout::TitleOnly),
8
9 // Slide 2: Centered Title (good for cover slides)
10 SlideContent::new("Centered Title Slide")
11 .layout(SlideLayout::CenteredTitle)
12 .title_size(60)
13 .title_color("4F81BD"),
14
15 // Slide 3: Title and Content (standard layout)
16 SlideContent::new("Standard Layout")
17 .add_bullet("Point 1: Title at top")
18 .add_bullet("Point 2: Content below")
19 .add_bullet("Point 3: Most common layout")
20 .layout(SlideLayout::TitleAndContent),
21
22 // Slide 4: Title and Big Content
23 SlideContent::new("Big Content Area")
24 .add_bullet("More space for content")
25 .add_bullet("Smaller title area")
26 .add_bullet("Good for detailed slides")
27 .add_bullet("Maximizes content space")
28 .layout(SlideLayout::TitleAndBigContent),
29
30 // Slide 5: Two Column Layout
31 SlideContent::new("Two Column Layout")
32 .add_bullet("Left column content")
33 .add_bullet("Organized side by side")
34 .add_bullet("Great for comparisons")
35 .layout(SlideLayout::TwoColumn),
36
37 // Slide 6: Blank Slide
38 SlideContent::new("")
39 .layout(SlideLayout::Blank),
40
41 // Slide 7: Summary with different formatting
42 SlideContent::new("Summary")
43 .title_size(48)
44 .title_bold(true)
45 .title_color("C0504D")
46 .add_bullet("Layout types implemented:")
47 .add_bullet("• TitleOnly - Just title")
48 .add_bullet("• CenteredTitle - Title centered")
49 .add_bullet("• TitleAndContent - Standard")
50 .add_bullet("• TitleAndBigContent - Large content")
51 .add_bullet("• TwoColumn - Side by side")
52 .add_bullet("• Blank - Empty slide")
53 .content_size(20)
54 .layout(SlideLayout::TitleAndContent),
55 ];
56
57 let pptx_data = create_pptx_with_content("Layout Demo Presentation", slides)?;
58 std::fs::write("layout_demo.pptx", pptx_data)?;
59 println!("✓ Created layout_demo.pptx with 7 slides demonstrating different layouts");
60
61 Ok(())
62}Sourcepub fn content_bold(self, bold: bool) -> Self
pub fn content_bold(self, bold: bool) -> Self
Examples found in repository?
68fn create_bold_content_example() -> Result<(), Box<dyn std::error::Error>> {
69 let slides = vec![
70 SlideContent::new("Bold Content Slide")
71 .title_bold(true)
72 .content_bold(true) // Make bullets bold
73 .add_bullet("Bold bullet point 1")
74 .add_bullet("Bold bullet point 2")
75 .add_bullet("Bold bullet point 3"),
76 SlideContent::new("Regular Content")
77 .title_bold(true)
78 .content_bold(false) // Regular bullets
79 .add_bullet("Regular bullet point 1")
80 .add_bullet("Regular bullet point 2"),
81 ];
82
83 let pptx_data = create_pptx_with_content("Bold Content Example", slides)?;
84 fs::write("examples/output/bold_content.pptx", pptx_data)?;
85 Ok(())
86}
87
88fn create_mixed_formatting_example() -> Result<(), Box<dyn std::error::Error>> {
89 let slides = vec![
90 SlideContent::new("Title Slide")
91 .title_size(52)
92 .title_bold(true)
93 .content_size(24)
94 .content_bold(false)
95 .add_bullet("Large content text")
96 .add_bullet("Still readable")
97 .add_bullet("Professional look"),
98 SlideContent::new("Compact Slide")
99 .title_size(36)
100 .title_bold(false)
101 .content_size(18)
102 .content_bold(true)
103 .add_bullet("Smaller title")
104 .add_bullet("Bold content")
105 .add_bullet("Tight spacing"),
106 SlideContent::new("Summary")
107 .title_size(48)
108 .title_bold(true)
109 .content_size(32)
110 .content_bold(true)
111 .add_bullet("Large bold text")
112 .add_bullet("High impact")
113 .add_bullet("Great for emphasis"),
114 ];
115
116 let pptx_data = create_pptx_with_content("Mixed Formatting Example", slides)?;
117 fs::write("examples/output/mixed_formatting.pptx", pptx_data)?;
118 Ok(())
119}More examples
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}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}14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 println!("╔════════════════════════════════════════════════════════════╗");
16 println!("║ PPTX Editing Demo ║");
17 println!("╚════════════════════════════════════════════════════════════╝\n");
18
19 // =========================================================================
20 // Step 1: Create an initial presentation
21 // =========================================================================
22 println!("📝 Step 1: Creating initial presentation...");
23
24 let initial_slides = vec![
25 SlideContent::new("Original Presentation")
26 .layout(SlideLayout::CenteredTitle)
27 .title_bold(true)
28 .title_color("1F497D"),
29
30 SlideContent::new("Slide 1: Introduction")
31 .add_bullet("This is the original content")
32 .add_bullet("Created programmatically"),
33
34 SlideContent::new("Slide 2: Features")
35 .add_bullet("Feature A")
36 .add_bullet("Feature B")
37 .add_bullet("Feature C"),
38 ];
39
40 let pptx_data = create_pptx_with_content("Original Presentation", initial_slides)?;
41 fs::write("original.pptx", &pptx_data)?;
42 println!(" ✓ Created original.pptx with 3 slides\n");
43
44 // =========================================================================
45 // Step 2: Open and inspect the presentation
46 // =========================================================================
47 println!("📖 Step 2: Opening presentation for editing...");
48
49 let mut editor = PresentationEditor::open("original.pptx")?;
50 println!(" ✓ Opened original.pptx");
51 println!(" ├── Slide count: {}", editor.slide_count());
52
53 // Read first slide
54 let slide0 = editor.get_slide(0)?;
55 println!(" └── First slide title: {:?}\n", slide0.title);
56
57 // =========================================================================
58 // Step 3: Add new slides
59 // =========================================================================
60 println!("➕ Step 3: Adding new slides...");
61
62 // Add a new slide at the end
63 let new_slide1 = SlideContent::new("New Slide: Added via Editor")
64 .add_bullet("This slide was added programmatically")
65 .add_bullet("Using PresentationEditor")
66 .add_bullet("After the presentation was created")
67 .title_color("9BBB59");
68
69 let idx1 = editor.add_slide(new_slide1)?;
70 println!(" ✓ Added slide at index {}", idx1);
71
72 // Add another slide
73 let new_slide2 = SlideContent::new("Another New Slide")
74 .layout(SlideLayout::TwoColumn)
75 .add_bullet("Left column item 1")
76 .add_bullet("Left column item 2")
77 .add_bullet("Right column item 1")
78 .add_bullet("Right column item 2");
79
80 let idx2 = editor.add_slide(new_slide2)?;
81 println!(" ✓ Added slide at index {}", idx2);
82 println!(" └── Total slides now: {}\n", editor.slide_count());
83
84 // =========================================================================
85 // Step 4: Update existing slide
86 // =========================================================================
87 println!("✏️ Step 4: Updating existing slide...");
88
89 let updated_slide = SlideContent::new("Slide 2: Updated Features")
90 .add_bullet("Feature A - Enhanced!")
91 .add_bullet("Feature B - Improved!")
92 .add_bullet("Feature C - Optimized!")
93 .add_bullet("Feature D - NEW!")
94 .title_color("C0504D")
95 .content_bold(true);
96
97 editor.update_slide(2, updated_slide)?;
98 println!(" ✓ Updated slide at index 2\n");
99
100 // =========================================================================
101 // Step 5: Save modified presentation
102 // =========================================================================
103 println!("💾 Step 5: Saving modified presentation...");
104
105 editor.save("modified.pptx")?;
106 println!(" ✓ Saved as modified.pptx\n");
107
108 // =========================================================================
109 // Step 6: Verify the changes
110 // =========================================================================
111 println!("🔍 Step 6: Verifying changes...");
112
113 let reader = PresentationReader::open("modified.pptx")?;
114 println!(" Modified presentation:");
115 println!(" ├── Slide count: {}", reader.slide_count());
116
117 for i in 0..reader.slide_count() {
118 let slide = reader.get_slide(i)?;
119 let title = slide.title.as_deref().unwrap_or("(no title)");
120 let bullets = slide.body_text.len();
121 println!(" {}── Slide {}: \"{}\" ({} bullets)",
122 if i == reader.slide_count() - 1 { "└" } else { "├" },
123 i + 1,
124 title,
125 bullets);
126 }
127
128 // =========================================================================
129 // Step 7: Demonstrate slide removal
130 // =========================================================================
131 println!("\n🗑️ Step 7: Demonstrating slide removal...");
132
133 let mut editor2 = PresentationEditor::open("modified.pptx")?;
134 println!(" Before removal: {} slides", editor2.slide_count());
135
136 // Remove the last slide
137 editor2.remove_slide(editor2.slide_count() - 1)?;
138 println!(" ✓ Removed last slide");
139 println!(" After removal: {} slides", editor2.slide_count());
140
141 editor2.save("trimmed.pptx")?;
142 println!(" ✓ Saved as trimmed.pptx");
143
144 // Cleanup
145 fs::remove_file("original.pptx").ok();
146 fs::remove_file("modified.pptx").ok();
147 fs::remove_file("trimmed.pptx").ok();
148
149 // =========================================================================
150 // Summary
151 // =========================================================================
152 println!("\n╔════════════════════════════════════════════════════════════╗");
153 println!("║ Demo Complete ║");
154 println!("╠════════════════════════════════════════════════════════════╣");
155 println!("║ Capabilities Demonstrated: ║");
156 println!("║ ✓ PresentationEditor::open() - Open for editing ║");
157 println!("║ ✓ editor.add_slide() - Add new slides ║");
158 println!("║ ✓ editor.update_slide() - Modify existing slides ║");
159 println!("║ ✓ editor.remove_slide() - Remove slides ║");
160 println!("║ ✓ editor.save() - Save modified presentation ║");
161 println!("║ ✓ editor.get_slide() - Read slide content ║");
162 println!("╚════════════════════════════════════════════════════════════╝");
163
164 Ok(())
165}68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn title_italic(self, italic: bool) -> Self
pub fn title_italic(self, italic: bool) -> Self
Examples found in repository?
53fn create_italic_underline_example() -> Result<(), Box<dyn std::error::Error>> {
54 let slides = vec![
55 SlideContent::new("Italic Text")
56 .title_italic(true)
57 .add_bullet("This is italic content")
58 .add_bullet("More italic text here"),
59 SlideContent::new("Underlined Text")
60 .title_underline(true)
61 .content_underline(true)
62 .add_bullet("Underlined bullet point 1")
63 .add_bullet("Underlined bullet point 2"),
64 SlideContent::new("Combined Effects")
65 .title_italic(true)
66 .title_underline(true)
67 .content_italic(true)
68 .add_bullet("Italic and underlined content")
69 .add_bullet("Multiple effects combined"),
70 ];
71
72 let pptx_data = create_pptx_with_content("Italic and Underline", slides)?;
73 fs::write("examples/output/italic_underline.pptx", pptx_data)?;
74 Ok(())
75}
76
77fn create_colored_text_example() -> Result<(), Box<dyn std::error::Error>> {
78 let slides = vec![
79 SlideContent::new("Red Title")
80 .title_color("FF0000")
81 .add_bullet("Red title text")
82 .add_bullet("Regular content"),
83 SlideContent::new("Blue Content")
84 .content_color("0000FF")
85 .add_bullet("Blue bullet point 1")
86 .add_bullet("Blue bullet point 2")
87 .add_bullet("Blue bullet point 3"),
88 SlideContent::new("Green Title & Content")
89 .title_color("00AA00")
90 .content_color("00AA00")
91 .add_bullet("Green title and content")
92 .add_bullet("All text is green"),
93 SlideContent::new("Purple Accent")
94 .title_color("9933FF")
95 .add_bullet("Purple title")
96 .add_bullet("Regular content"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Colored Text", slides)?;
100 fs::write("examples/output/colored_text.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn content_italic(self, italic: bool) -> Self
pub fn content_italic(self, italic: bool) -> Self
Examples found in repository?
53fn create_italic_underline_example() -> Result<(), Box<dyn std::error::Error>> {
54 let slides = vec![
55 SlideContent::new("Italic Text")
56 .title_italic(true)
57 .add_bullet("This is italic content")
58 .add_bullet("More italic text here"),
59 SlideContent::new("Underlined Text")
60 .title_underline(true)
61 .content_underline(true)
62 .add_bullet("Underlined bullet point 1")
63 .add_bullet("Underlined bullet point 2"),
64 SlideContent::new("Combined Effects")
65 .title_italic(true)
66 .title_underline(true)
67 .content_italic(true)
68 .add_bullet("Italic and underlined content")
69 .add_bullet("Multiple effects combined"),
70 ];
71
72 let pptx_data = create_pptx_with_content("Italic and Underline", slides)?;
73 fs::write("examples/output/italic_underline.pptx", pptx_data)?;
74 Ok(())
75}
76
77fn create_colored_text_example() -> Result<(), Box<dyn std::error::Error>> {
78 let slides = vec![
79 SlideContent::new("Red Title")
80 .title_color("FF0000")
81 .add_bullet("Red title text")
82 .add_bullet("Regular content"),
83 SlideContent::new("Blue Content")
84 .content_color("0000FF")
85 .add_bullet("Blue bullet point 1")
86 .add_bullet("Blue bullet point 2")
87 .add_bullet("Blue bullet point 3"),
88 SlideContent::new("Green Title & Content")
89 .title_color("00AA00")
90 .content_color("00AA00")
91 .add_bullet("Green title and content")
92 .add_bullet("All text is green"),
93 SlideContent::new("Purple Accent")
94 .title_color("9933FF")
95 .add_bullet("Purple title")
96 .add_bullet("Regular content"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Colored Text", slides)?;
100 fs::write("examples/output/colored_text.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn title_underline(self, underline: bool) -> Self
pub fn title_underline(self, underline: bool) -> Self
Examples found in repository?
53fn create_italic_underline_example() -> Result<(), Box<dyn std::error::Error>> {
54 let slides = vec![
55 SlideContent::new("Italic Text")
56 .title_italic(true)
57 .add_bullet("This is italic content")
58 .add_bullet("More italic text here"),
59 SlideContent::new("Underlined Text")
60 .title_underline(true)
61 .content_underline(true)
62 .add_bullet("Underlined bullet point 1")
63 .add_bullet("Underlined bullet point 2"),
64 SlideContent::new("Combined Effects")
65 .title_italic(true)
66 .title_underline(true)
67 .content_italic(true)
68 .add_bullet("Italic and underlined content")
69 .add_bullet("Multiple effects combined"),
70 ];
71
72 let pptx_data = create_pptx_with_content("Italic and Underline", slides)?;
73 fs::write("examples/output/italic_underline.pptx", pptx_data)?;
74 Ok(())
75}
76
77fn create_colored_text_example() -> Result<(), Box<dyn std::error::Error>> {
78 let slides = vec![
79 SlideContent::new("Red Title")
80 .title_color("FF0000")
81 .add_bullet("Red title text")
82 .add_bullet("Regular content"),
83 SlideContent::new("Blue Content")
84 .content_color("0000FF")
85 .add_bullet("Blue bullet point 1")
86 .add_bullet("Blue bullet point 2")
87 .add_bullet("Blue bullet point 3"),
88 SlideContent::new("Green Title & Content")
89 .title_color("00AA00")
90 .content_color("00AA00")
91 .add_bullet("Green title and content")
92 .add_bullet("All text is green"),
93 SlideContent::new("Purple Accent")
94 .title_color("9933FF")
95 .add_bullet("Purple title")
96 .add_bullet("Regular content"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Colored Text", slides)?;
100 fs::write("examples/output/colored_text.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn content_underline(self, underline: bool) -> Self
pub fn content_underline(self, underline: bool) -> Self
Examples found in repository?
53fn create_italic_underline_example() -> Result<(), Box<dyn std::error::Error>> {
54 let slides = vec![
55 SlideContent::new("Italic Text")
56 .title_italic(true)
57 .add_bullet("This is italic content")
58 .add_bullet("More italic text here"),
59 SlideContent::new("Underlined Text")
60 .title_underline(true)
61 .content_underline(true)
62 .add_bullet("Underlined bullet point 1")
63 .add_bullet("Underlined bullet point 2"),
64 SlideContent::new("Combined Effects")
65 .title_italic(true)
66 .title_underline(true)
67 .content_italic(true)
68 .add_bullet("Italic and underlined content")
69 .add_bullet("Multiple effects combined"),
70 ];
71
72 let pptx_data = create_pptx_with_content("Italic and Underline", slides)?;
73 fs::write("examples/output/italic_underline.pptx", pptx_data)?;
74 Ok(())
75}
76
77fn create_colored_text_example() -> Result<(), Box<dyn std::error::Error>> {
78 let slides = vec![
79 SlideContent::new("Red Title")
80 .title_color("FF0000")
81 .add_bullet("Red title text")
82 .add_bullet("Regular content"),
83 SlideContent::new("Blue Content")
84 .content_color("0000FF")
85 .add_bullet("Blue bullet point 1")
86 .add_bullet("Blue bullet point 2")
87 .add_bullet("Blue bullet point 3"),
88 SlideContent::new("Green Title & Content")
89 .title_color("00AA00")
90 .content_color("00AA00")
91 .add_bullet("Green title and content")
92 .add_bullet("All text is green"),
93 SlideContent::new("Purple Accent")
94 .title_color("9933FF")
95 .add_bullet("Purple title")
96 .add_bullet("Regular content"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Colored Text", slides)?;
100 fs::write("examples/output/colored_text.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn title_color(self, color: &str) -> Self
pub fn title_color(self, color: &str) -> Self
Examples found in repository?
77fn create_colored_text_example() -> Result<(), Box<dyn std::error::Error>> {
78 let slides = vec![
79 SlideContent::new("Red Title")
80 .title_color("FF0000")
81 .add_bullet("Red title text")
82 .add_bullet("Regular content"),
83 SlideContent::new("Blue Content")
84 .content_color("0000FF")
85 .add_bullet("Blue bullet point 1")
86 .add_bullet("Blue bullet point 2")
87 .add_bullet("Blue bullet point 3"),
88 SlideContent::new("Green Title & Content")
89 .title_color("00AA00")
90 .content_color("00AA00")
91 .add_bullet("Green title and content")
92 .add_bullet("All text is green"),
93 SlideContent::new("Purple Accent")
94 .title_color("9933FF")
95 .add_bullet("Purple title")
96 .add_bullet("Regular content"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Colored Text", slides)?;
100 fs::write("examples/output/colored_text.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}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}13fn main() -> Result<(), Box<dyn std::error::Error>> {
14 println!("=== Alignment Test: ppt-rs vs python-pptx ===\n");
15
16 // Create output directory
17 fs::create_dir_all("examples/output")?;
18
19 // Create slides matching the reference presentation structure
20 let slides = vec![
21 // Slide 1: Title Slide
22 SlideContent::new("Alignment Test Presentation")
23 .title_size(54)
24 .title_bold(true)
25 .title_color("003366"), // RGB(0, 51, 102)
26
27 // Slide 2: Content Slide
28 SlideContent::new("Shapes and Formatting")
29 .title_size(44)
30 .title_bold(true)
31 .title_color("003366")
32 .add_bullet("Text formatting (bold, colors, sizes)")
33 .add_bullet("Shape creation and positioning")
34 .add_bullet("Multiple slides and layouts"),
35 ];
36
37 // Generate PPTX
38 let pptx_data = create_pptx_with_content(
39 "Alignment Test Presentation",
40 slides,
41 )?;
42
43 // Write to file
44 let output_path = "examples/output/alignment_test_ppt_rs.pptx";
45 fs::write(output_path, pptx_data)?;
46
47 println!("✓ Created presentation: {output_path}");
48 println!(" - Title: Alignment Test Presentation");
49 println!(" - Slides: 2");
50 println!("\nNext steps:");
51 println!(" 1. Generate reference: python3 scripts/generate_reference.py");
52 println!(" 2. Compare files: python3 scripts/compare_pptx.py");
53
54 Ok(())
55}3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title Only
6 SlideContent::new("Welcome to Layout Demo")
7 .layout(SlideLayout::TitleOnly),
8
9 // Slide 2: Centered Title (good for cover slides)
10 SlideContent::new("Centered Title Slide")
11 .layout(SlideLayout::CenteredTitle)
12 .title_size(60)
13 .title_color("4F81BD"),
14
15 // Slide 3: Title and Content (standard layout)
16 SlideContent::new("Standard Layout")
17 .add_bullet("Point 1: Title at top")
18 .add_bullet("Point 2: Content below")
19 .add_bullet("Point 3: Most common layout")
20 .layout(SlideLayout::TitleAndContent),
21
22 // Slide 4: Title and Big Content
23 SlideContent::new("Big Content Area")
24 .add_bullet("More space for content")
25 .add_bullet("Smaller title area")
26 .add_bullet("Good for detailed slides")
27 .add_bullet("Maximizes content space")
28 .layout(SlideLayout::TitleAndBigContent),
29
30 // Slide 5: Two Column Layout
31 SlideContent::new("Two Column Layout")
32 .add_bullet("Left column content")
33 .add_bullet("Organized side by side")
34 .add_bullet("Great for comparisons")
35 .layout(SlideLayout::TwoColumn),
36
37 // Slide 6: Blank Slide
38 SlideContent::new("")
39 .layout(SlideLayout::Blank),
40
41 // Slide 7: Summary with different formatting
42 SlideContent::new("Summary")
43 .title_size(48)
44 .title_bold(true)
45 .title_color("C0504D")
46 .add_bullet("Layout types implemented:")
47 .add_bullet("• TitleOnly - Just title")
48 .add_bullet("• CenteredTitle - Title centered")
49 .add_bullet("• TitleAndContent - Standard")
50 .add_bullet("• TitleAndBigContent - Large content")
51 .add_bullet("• TwoColumn - Side by side")
52 .add_bullet("• Blank - Empty slide")
53 .content_size(20)
54 .layout(SlideLayout::TitleAndContent),
55 ];
56
57 let pptx_data = create_pptx_with_content("Layout Demo Presentation", slides)?;
58 std::fs::write("layout_demo.pptx", pptx_data)?;
59 println!("✓ Created layout_demo.pptx with 7 slides demonstrating different layouts");
60
61 Ok(())
62}14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 println!("╔════════════════════════════════════════════════════════════╗");
16 println!("║ PPTX Editing Demo ║");
17 println!("╚════════════════════════════════════════════════════════════╝\n");
18
19 // =========================================================================
20 // Step 1: Create an initial presentation
21 // =========================================================================
22 println!("📝 Step 1: Creating initial presentation...");
23
24 let initial_slides = vec![
25 SlideContent::new("Original Presentation")
26 .layout(SlideLayout::CenteredTitle)
27 .title_bold(true)
28 .title_color("1F497D"),
29
30 SlideContent::new("Slide 1: Introduction")
31 .add_bullet("This is the original content")
32 .add_bullet("Created programmatically"),
33
34 SlideContent::new("Slide 2: Features")
35 .add_bullet("Feature A")
36 .add_bullet("Feature B")
37 .add_bullet("Feature C"),
38 ];
39
40 let pptx_data = create_pptx_with_content("Original Presentation", initial_slides)?;
41 fs::write("original.pptx", &pptx_data)?;
42 println!(" ✓ Created original.pptx with 3 slides\n");
43
44 // =========================================================================
45 // Step 2: Open and inspect the presentation
46 // =========================================================================
47 println!("📖 Step 2: Opening presentation for editing...");
48
49 let mut editor = PresentationEditor::open("original.pptx")?;
50 println!(" ✓ Opened original.pptx");
51 println!(" ├── Slide count: {}", editor.slide_count());
52
53 // Read first slide
54 let slide0 = editor.get_slide(0)?;
55 println!(" └── First slide title: {:?}\n", slide0.title);
56
57 // =========================================================================
58 // Step 3: Add new slides
59 // =========================================================================
60 println!("➕ Step 3: Adding new slides...");
61
62 // Add a new slide at the end
63 let new_slide1 = SlideContent::new("New Slide: Added via Editor")
64 .add_bullet("This slide was added programmatically")
65 .add_bullet("Using PresentationEditor")
66 .add_bullet("After the presentation was created")
67 .title_color("9BBB59");
68
69 let idx1 = editor.add_slide(new_slide1)?;
70 println!(" ✓ Added slide at index {}", idx1);
71
72 // Add another slide
73 let new_slide2 = SlideContent::new("Another New Slide")
74 .layout(SlideLayout::TwoColumn)
75 .add_bullet("Left column item 1")
76 .add_bullet("Left column item 2")
77 .add_bullet("Right column item 1")
78 .add_bullet("Right column item 2");
79
80 let idx2 = editor.add_slide(new_slide2)?;
81 println!(" ✓ Added slide at index {}", idx2);
82 println!(" └── Total slides now: {}\n", editor.slide_count());
83
84 // =========================================================================
85 // Step 4: Update existing slide
86 // =========================================================================
87 println!("✏️ Step 4: Updating existing slide...");
88
89 let updated_slide = SlideContent::new("Slide 2: Updated Features")
90 .add_bullet("Feature A - Enhanced!")
91 .add_bullet("Feature B - Improved!")
92 .add_bullet("Feature C - Optimized!")
93 .add_bullet("Feature D - NEW!")
94 .title_color("C0504D")
95 .content_bold(true);
96
97 editor.update_slide(2, updated_slide)?;
98 println!(" ✓ Updated slide at index 2\n");
99
100 // =========================================================================
101 // Step 5: Save modified presentation
102 // =========================================================================
103 println!("💾 Step 5: Saving modified presentation...");
104
105 editor.save("modified.pptx")?;
106 println!(" ✓ Saved as modified.pptx\n");
107
108 // =========================================================================
109 // Step 6: Verify the changes
110 // =========================================================================
111 println!("🔍 Step 6: Verifying changes...");
112
113 let reader = PresentationReader::open("modified.pptx")?;
114 println!(" Modified presentation:");
115 println!(" ├── Slide count: {}", reader.slide_count());
116
117 for i in 0..reader.slide_count() {
118 let slide = reader.get_slide(i)?;
119 let title = slide.title.as_deref().unwrap_or("(no title)");
120 let bullets = slide.body_text.len();
121 println!(" {}── Slide {}: \"{}\" ({} bullets)",
122 if i == reader.slide_count() - 1 { "└" } else { "├" },
123 i + 1,
124 title,
125 bullets);
126 }
127
128 // =========================================================================
129 // Step 7: Demonstrate slide removal
130 // =========================================================================
131 println!("\n🗑️ Step 7: Demonstrating slide removal...");
132
133 let mut editor2 = PresentationEditor::open("modified.pptx")?;
134 println!(" Before removal: {} slides", editor2.slide_count());
135
136 // Remove the last slide
137 editor2.remove_slide(editor2.slide_count() - 1)?;
138 println!(" ✓ Removed last slide");
139 println!(" After removal: {} slides", editor2.slide_count());
140
141 editor2.save("trimmed.pptx")?;
142 println!(" ✓ Saved as trimmed.pptx");
143
144 // Cleanup
145 fs::remove_file("original.pptx").ok();
146 fs::remove_file("modified.pptx").ok();
147 fs::remove_file("trimmed.pptx").ok();
148
149 // =========================================================================
150 // Summary
151 // =========================================================================
152 println!("\n╔════════════════════════════════════════════════════════════╗");
153 println!("║ Demo Complete ║");
154 println!("╠════════════════════════════════════════════════════════════╣");
155 println!("║ Capabilities Demonstrated: ║");
156 println!("║ ✓ PresentationEditor::open() - Open for editing ║");
157 println!("║ ✓ editor.add_slide() - Add new slides ║");
158 println!("║ ✓ editor.update_slide() - Modify existing slides ║");
159 println!("║ ✓ editor.remove_slide() - Remove slides ║");
160 println!("║ ✓ editor.save() - Save modified presentation ║");
161 println!("║ ✓ editor.get_slide() - Read slide content ║");
162 println!("╚════════════════════════════════════════════════════════════╝");
163
164 Ok(())
165}13fn main() -> Result<(), Box<dyn std::error::Error>> {
14 println!("╔════════════════════════════════════════════════════════════╗");
15 println!("║ PPTX Reading & Parsing Demo ║");
16 println!("╚════════════════════════════════════════════════════════════╝\n");
17
18 // =========================================================================
19 // Step 1: Create a sample PPTX to read
20 // =========================================================================
21 println!("📝 Step 1: Creating sample presentation...");
22
23 let slides = vec![
24 SlideContent::new("Welcome to PPTX-RS")
25 .layout(SlideLayout::CenteredTitle)
26 .title_bold(true)
27 .title_color("1F497D"),
28
29 SlideContent::new("Features Overview")
30 .add_bullet("Create presentations programmatically")
31 .add_bullet("Read existing PPTX files")
32 .add_bullet("Extract text and metadata")
33 .add_bullet("Parse shapes and tables"),
34
35 SlideContent::new("Technical Details")
36 .layout(SlideLayout::TwoColumn)
37 .add_bullet("XML parsing with xml-rs")
38 .add_bullet("ZIP handling with zip crate")
39 .add_bullet("ECMA-376 compliant")
40 .add_bullet("Rust 2024 edition")
41 .add_bullet("Cross-platform")
42 .add_bullet("No external dependencies"),
43
44 SlideContent::new("Summary")
45 .add_bullet("Full read/write support")
46 .add_bullet("Comprehensive API")
47 .add_bullet("Well tested"),
48 ];
49
50 let pptx_data = create_pptx_with_content("PPTX-RS Demo", slides)?;
51 fs::write("sample_presentation.pptx", &pptx_data)?;
52 println!(" ✓ Created sample_presentation.pptx ({} bytes)\n", pptx_data.len());
53
54 // =========================================================================
55 // Step 2: Open and read the presentation
56 // =========================================================================
57 println!("📖 Step 2: Opening presentation...");
58
59 let reader = PresentationReader::open("sample_presentation.pptx")?;
60 let info = reader.info();
61
62 println!(" Presentation Info:");
63 println!(" ├── Title: {}", info.title.as_deref().unwrap_or("(none)"));
64 println!(" ├── Creator: {}", info.creator.as_deref().unwrap_or("(none)"));
65 println!(" ├── Slides: {}", info.slide_count);
66 println!(" └── Revision: {}\n", info.revision.unwrap_or(0));
67
68 // =========================================================================
69 // Step 3: Parse each slide
70 // =========================================================================
71 println!("📑 Step 3: Parsing slides...");
72
73 for i in 0..reader.slide_count() {
74 let slide = reader.get_slide(i)?;
75
76 println!("\n Slide {}:", i + 1);
77 println!(" ├── Title: {}", slide.title.as_deref().unwrap_or("(none)"));
78 println!(" ├── Shapes: {}", slide.shapes.len());
79 println!(" ├── Tables: {}", slide.tables.len());
80
81 if !slide.body_text.is_empty() {
82 println!(" └── Body text:");
83 for (j, text) in slide.body_text.iter().enumerate() {
84 let prefix = if j == slide.body_text.len() - 1 { " └──" } else { " ├──" };
85 println!("{} {}", prefix, text);
86 }
87 } else {
88 println!(" └── Body text: (none)");
89 }
90 }
91
92 // =========================================================================
93 // Step 4: Extract all text
94 // =========================================================================
95 println!("\n📋 Step 4: Extracting all text...");
96
97 let all_text = reader.extract_all_text()?;
98 println!(" Found {} text items:", all_text.len());
99 for (i, text) in all_text.iter().take(10).enumerate() {
100 println!(" {}. {}", i + 1, text);
101 }
102 if all_text.len() > 10 {
103 println!(" ... and {} more", all_text.len() - 10);
104 }
105
106 // =========================================================================
107 // Step 5: Direct XML parsing (advanced)
108 // =========================================================================
109 println!("\n🔧 Step 5: Direct XML parsing (advanced)...");
110
111 // You can also parse slide XML directly
112 let sample_xml = r#"<?xml version="1.0" encoding="UTF-8"?>
113 <p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
114 xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
115 <p:cSld>
116 <p:spTree>
117 <p:sp>
118 <p:nvSpPr>
119 <p:cNvPr id="2" name="Title"/>
120 <p:nvPr><p:ph type="title"/></p:nvPr>
121 </p:nvSpPr>
122 <p:txBody>
123 <a:p>
124 <a:r>
125 <a:rPr b="1" sz="4400"/>
126 <a:t>Direct Parse Example</a:t>
127 </a:r>
128 </a:p>
129 </p:txBody>
130 </p:sp>
131 </p:spTree>
132 </p:cSld>
133 </p:sld>"#;
134
135 let parsed = SlideParser::parse(sample_xml)?;
136 println!(" Parsed XML directly:");
137 println!(" ├── Title: {}", parsed.title.as_deref().unwrap_or("(none)"));
138 println!(" └── Shapes: {}", parsed.shapes.len());
139
140 if let Some(shape) = parsed.shapes.first() {
141 if let Some(para) = shape.paragraphs.first() {
142 if let Some(run) = para.runs.first() {
143 println!("\n Text formatting detected:");
144 println!(" ├── Bold: {}", run.bold);
145 println!(" ├── Font size: {:?}", run.font_size);
146 println!(" └── Text: {}", run.text);
147 }
148 }
149 }
150
151 // Cleanup
152 fs::remove_file("sample_presentation.pptx").ok();
153
154 // =========================================================================
155 // Summary
156 // =========================================================================
157 println!("\n╔════════════════════════════════════════════════════════════╗");
158 println!("║ Demo Complete ║");
159 println!("╠════════════════════════════════════════════════════════════╣");
160 println!("║ Capabilities Demonstrated: ║");
161 println!("║ ✓ PresentationReader::open() - Open PPTX files ║");
162 println!("║ ✓ reader.info() - Get presentation metadata ║");
163 println!("║ ✓ reader.get_slide(i) - Parse individual slides ║");
164 println!("║ ✓ reader.extract_all_text() - Extract all text ║");
165 println!("║ ✓ SlideParser::parse() - Direct XML parsing ║");
166 println!("╚════════════════════════════════════════════════════════════╝");
167
168 Ok(())
169}Sourcepub fn content_color(self, color: &str) -> Self
pub fn content_color(self, color: &str) -> Self
Examples found in repository?
77fn create_colored_text_example() -> Result<(), Box<dyn std::error::Error>> {
78 let slides = vec![
79 SlideContent::new("Red Title")
80 .title_color("FF0000")
81 .add_bullet("Red title text")
82 .add_bullet("Regular content"),
83 SlideContent::new("Blue Content")
84 .content_color("0000FF")
85 .add_bullet("Blue bullet point 1")
86 .add_bullet("Blue bullet point 2")
87 .add_bullet("Blue bullet point 3"),
88 SlideContent::new("Green Title & Content")
89 .title_color("00AA00")
90 .content_color("00AA00")
91 .add_bullet("Green title and content")
92 .add_bullet("All text is green"),
93 SlideContent::new("Purple Accent")
94 .title_color("9933FF")
95 .add_bullet("Purple title")
96 .add_bullet("Regular content"),
97 ];
98
99 let pptx_data = create_pptx_with_content("Colored Text", slides)?;
100 fs::write("examples/output/colored_text.pptx", pptx_data)?;
101 Ok(())
102}
103
104fn create_combined_styling_example() -> Result<(), Box<dyn std::error::Error>> {
105 let slides = vec![
106 SlideContent::new("Bold & Italic & Red")
107 .title_bold(true)
108 .title_italic(true)
109 .title_color("FF0000")
110 .title_size(52)
111 .add_bullet("Regular content"),
112 SlideContent::new("Underlined Blue Content")
113 .content_underline(true)
114 .content_color("0000FF")
115 .content_bold(true)
116 .add_bullet("Bold, underlined, blue bullet")
117 .add_bullet("Multiple effects applied"),
118 SlideContent::new("Mixed Effects")
119 .title_italic(true)
120 .title_color("FF6600")
121 .content_bold(true)
122 .content_underline(true)
123 .content_color("0066FF")
124 .add_bullet("Title: italic, orange")
125 .add_bullet("Content: bold, underlined, blue"),
126 SlideContent::new("Professional Look")
127 .title_bold(true)
128 .title_size(48)
129 .title_color("003366")
130 .content_size(24)
131 .add_bullet("Clean, professional styling")
132 .add_bullet("Dark blue title with bold")
133 .add_bullet("Larger content text"),
134 ];
135
136 let pptx_data = create_pptx_with_content("Combined Styling", slides)?;
137 fs::write("examples/output/combined_styling.pptx", pptx_data)?;
138 Ok(())
139}
140
141fn create_professional_example() -> Result<(), Box<dyn std::error::Error>> {
142 let slides = vec![
143 SlideContent::new("Company Presentation")
144 .title_bold(true)
145 .title_size(56)
146 .title_color("003366")
147 .content_size(32)
148 .add_bullet("2025 Annual Review"),
149 SlideContent::new("Key Highlights")
150 .title_bold(true)
151 .title_color("003366")
152 .content_bold(true)
153 .content_color("0066CC")
154 .add_bullet("Revenue growth: +25%")
155 .add_bullet("Market expansion: 3 new regions")
156 .add_bullet("Team growth: +50 employees"),
157 SlideContent::new("Strategic Initiatives")
158 .title_italic(true)
159 .title_color("FF6600")
160 .content_underline(true)
161 .add_bullet("Digital transformation")
162 .add_bullet("Customer experience improvement")
163 .add_bullet("Sustainability focus"),
164 SlideContent::new("Q1 2025 Goals")
165 .title_bold(true)
166 .title_underline(true)
167 .title_color("003366")
168 .content_bold(true)
169 .add_bullet("Launch new product line")
170 .add_bullet("Expand to 5 new markets")
171 .add_bullet("Achieve 30% revenue growth"),
172 SlideContent::new("Thank You")
173 .title_bold(true)
174 .title_size(60)
175 .title_color("003366")
176 .content_italic(true)
177 .content_size(28)
178 .add_bullet("Questions & Discussion"),
179 ];
180
181 let pptx_data = create_pptx_with_content("Professional Presentation", slides)?;
182 fs::write("examples/output/professional.pptx", pptx_data)?;
183 Ok(())
184}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}pub fn with_table(self) -> Self
Sourcepub fn with_chart(self) -> Self
pub fn with_chart(self) -> Self
Examples found in repository?
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}pub fn with_image(self) -> Self
Sourcepub fn layout(self, layout: SlideLayout) -> Self
pub fn layout(self, layout: SlideLayout) -> Self
Examples found in repository?
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 println!("Creating test presentation with speaker notes...");
8
9 let slides = vec![
10 SlideContent::new("Slide 1 - With Notes")
11 .layout(SlideLayout::CenteredTitle)
12 .title_size(54)
13 .title_bold(true)
14 .notes("This is a speaker note for slide 1. It should appear in presenter view."),
15
16 SlideContent::new("Slide 2 - Also With Notes")
17 .add_bullet("Bullet point 1")
18 .add_bullet("Bullet point 2")
19 .add_bullet("Bullet point 3")
20 .notes("Notes for slide 2 with bullet points."),
21
22 SlideContent::new("Slide 3 - No Notes")
23 .add_bullet("This slide has no notes"),
24
25 SlideContent::new("Slide 4 - More Notes")
26 .layout(SlideLayout::TwoColumn)
27 .add_bullet("Left 1")
28 .add_bullet("Left 2")
29 .add_bullet("Right 1")
30 .add_bullet("Right 2")
31 .notes("Two column layout with speaker notes."),
32 ];
33
34 let pptx_data = create_pptx_with_content("Test Notes", slides)?;
35 fs::write("test_notes.pptx", &pptx_data)?;
36 println!("Created test_notes.pptx ({} bytes)", pptx_data.len());
37 println!("\nOpen in PowerPoint and check presenter view for notes!");
38
39 Ok(())
40}More examples
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title Only
6 SlideContent::new("Welcome to Layout Demo")
7 .layout(SlideLayout::TitleOnly),
8
9 // Slide 2: Centered Title (good for cover slides)
10 SlideContent::new("Centered Title Slide")
11 .layout(SlideLayout::CenteredTitle)
12 .title_size(60)
13 .title_color("4F81BD"),
14
15 // Slide 3: Title and Content (standard layout)
16 SlideContent::new("Standard Layout")
17 .add_bullet("Point 1: Title at top")
18 .add_bullet("Point 2: Content below")
19 .add_bullet("Point 3: Most common layout")
20 .layout(SlideLayout::TitleAndContent),
21
22 // Slide 4: Title and Big Content
23 SlideContent::new("Big Content Area")
24 .add_bullet("More space for content")
25 .add_bullet("Smaller title area")
26 .add_bullet("Good for detailed slides")
27 .add_bullet("Maximizes content space")
28 .layout(SlideLayout::TitleAndBigContent),
29
30 // Slide 5: Two Column Layout
31 SlideContent::new("Two Column Layout")
32 .add_bullet("Left column content")
33 .add_bullet("Organized side by side")
34 .add_bullet("Great for comparisons")
35 .layout(SlideLayout::TwoColumn),
36
37 // Slide 6: Blank Slide
38 SlideContent::new("")
39 .layout(SlideLayout::Blank),
40
41 // Slide 7: Summary with different formatting
42 SlideContent::new("Summary")
43 .title_size(48)
44 .title_bold(true)
45 .title_color("C0504D")
46 .add_bullet("Layout types implemented:")
47 .add_bullet("• TitleOnly - Just title")
48 .add_bullet("• CenteredTitle - Title centered")
49 .add_bullet("• TitleAndContent - Standard")
50 .add_bullet("• TitleAndBigContent - Large content")
51 .add_bullet("• TwoColumn - Side by side")
52 .add_bullet("• Blank - Empty slide")
53 .content_size(20)
54 .layout(SlideLayout::TitleAndContent),
55 ];
56
57 let pptx_data = create_pptx_with_content("Layout Demo Presentation", slides)?;
58 std::fs::write("layout_demo.pptx", pptx_data)?;
59 println!("✓ Created layout_demo.pptx with 7 slides demonstrating different layouts");
60
61 Ok(())
62}21fn main() -> Result<(), Box<dyn std::error::Error>> {
22 println!("=== New PPT Elements Demo ===\n");
23
24 // Create slides demonstrating new features
25 let slides = vec![
26 // Slide 1: Title slide
27 SlideContent::new("New PPT Elements in ppt-rs")
28 .add_bullet("18 new chart types")
29 .add_bullet("Connectors between shapes")
30 .add_bullet("Hyperlinks (URL, slide, email)")
31 .add_bullet("Gradient fills")
32 .add_bullet("Video/Audio embedding")
33 .layout(SlideLayout::TitleAndContent),
34
35 // Slide 2: New Chart Types
36 SlideContent::new("New Chart Types")
37 .add_bullet("Area charts (standard, stacked, 100% stacked)")
38 .add_bullet("Scatter charts (markers, lines, smooth)")
39 .add_bullet("Doughnut charts")
40 .add_bullet("Radar charts (standard, filled)")
41 .add_bullet("Bubble charts")
42 .add_bullet("Stock charts (HLC, OHLC)")
43 .add_bullet("Combo charts (bar + line)")
44 .layout(SlideLayout::TitleAndContent),
45
46 // Slide 3: Connector Types
47 SlideContent::new("Connector Types")
48 .add_bullet("Straight connectors")
49 .add_bullet("Elbow (bent) connectors")
50 .add_bullet("Curved connectors")
51 .add_bullet("Arrow heads (Triangle, Stealth, Diamond, Oval)")
52 .add_bullet("Connection sites (Top, Bottom, Left, Right, Corners)")
53 .layout(SlideLayout::TitleAndContent),
54
55 // Slide 4: Hyperlink Types
56 SlideContent::new("Hyperlink Support")
57 .add_bullet("URL links (external websites)")
58 .add_bullet("Slide links (navigate within presentation)")
59 .add_bullet("Email links (mailto:)")
60 .add_bullet("File links (local files)")
61 .add_bullet("Navigation (First, Last, Next, Previous slide)")
62 .layout(SlideLayout::TitleAndContent),
63
64 // Slide 5: Gradient Fills
65 SlideContent::new("Gradient Fill Support")
66 .add_bullet("Linear gradients (horizontal, vertical, diagonal)")
67 .add_bullet("Radial gradients")
68 .add_bullet("Rectangular gradients")
69 .add_bullet("Path gradients")
70 .add_bullet("Preset gradients (Blue, Green, Rainbow, etc.)")
71 .add_bullet("Custom gradient stops with transparency")
72 .layout(SlideLayout::TitleAndContent),
73
74 // Slide 6: Media Support
75 SlideContent::new("Video & Audio Support")
76 .add_bullet("Video formats: MP4, WMV, AVI, MOV, MKV, WebM")
77 .add_bullet("Audio formats: MP3, WAV, WMA, M4A, OGG, FLAC")
78 .add_bullet("Playback options: auto-play, loop, mute")
79 .add_bullet("Volume control")
80 .add_bullet("Start/end time trimming")
81 .layout(SlideLayout::TitleAndContent),
82 ];
83
84 // Generate the PPTX
85 let pptx_data = create_pptx_with_content("New Elements Demo", slides)?;
86
87 // Save to file
88 let output_path = "examples/output/new_elements_demo.pptx";
89 std::fs::create_dir_all("examples/output")?;
90 std::fs::write(output_path, &pptx_data)?;
91
92 println!("✓ Created presentation: {}", output_path);
93 println!("✓ File size: {} bytes", pptx_data.len());
94
95 // Demonstrate API usage
96 println!("\n=== API Examples ===\n");
97
98 // Chart types
99 println!("Chart Types:");
100 let chart_types = [
101 ChartType::Bar,
102 ChartType::BarHorizontal,
103 ChartType::BarStacked,
104 ChartType::Line,
105 ChartType::LineMarkers,
106 ChartType::Pie,
107 ChartType::Doughnut,
108 ChartType::Area,
109 ChartType::AreaStacked,
110 ChartType::Scatter,
111 ChartType::ScatterSmooth,
112 ChartType::Bubble,
113 ChartType::Radar,
114 ChartType::RadarFilled,
115 ChartType::StockHLC,
116 ChartType::Combo,
117 ];
118 for ct in &chart_types {
119 println!(" - {:?} -> {}", ct, ct.xml_element());
120 }
121
122 // Connector example
123 println!("\nConnector Example:");
124 let connector = Connector::elbow(
125 inches_to_emu(1.0), inches_to_emu(1.0),
126 inches_to_emu(5.0), inches_to_emu(3.0),
127 )
128 .with_color("0066CC")
129 .with_end_arrow(ArrowType::Triangle)
130 .connect_start(1, ConnectionSite::Right)
131 .connect_end(2, ConnectionSite::Left);
132 println!(" Type: {:?}", connector.connector_type);
133 println!(" End Arrow: {:?}", connector.end_arrow);
134
135 // Hyperlink example
136 println!("\nHyperlink Examples:");
137 let url_link = Hyperlink::url("https://example.com").with_tooltip("Visit Example");
138 let slide_link = Hyperlink::slide(3);
139 let email_link = Hyperlink::email("test@example.com");
140 println!(" URL: {:?}", url_link.action);
141 println!(" Slide: {:?}", slide_link.action);
142 println!(" Email: {:?}", email_link.action);
143
144 // Gradient example
145 println!("\nGradient Examples:");
146 let blue_gradient = PresetGradients::blue();
147 let rainbow = PresetGradients::rainbow();
148 let custom = GradientFill::linear(GradientDirection::DiagonalDown)
149 .add_stop(ppt_rs::GradientStop::start("FF0000"))
150 .add_stop(ppt_rs::GradientStop::end("0000FF"));
151 println!(" Blue gradient: {} stops", blue_gradient.stops.len());
152 println!(" Rainbow gradient: {} stops", rainbow.stops.len());
153 println!(" Custom gradient: {} stops", custom.stops.len());
154
155 // Video example
156 println!("\nVideo Example:");
157 if let Some(video) = Video::from_file("video.mp4", 0, 0, inches_to_emu(6.0), inches_to_emu(4.0)) {
158 let video = video.with_options(VideoOptions::auto_play().with_loop(true));
159 println!(" Format: {:?}", video.format);
160 println!(" Auto-play: {}", video.options.auto_play);
161 println!(" Loop: {}", video.options.loop_playback);
162 }
163
164 // Audio example
165 println!("\nAudio Example:");
166 if let Some(audio) = Audio::from_file("audio.mp3", 0, 0, inches_to_emu(1.0), inches_to_emu(1.0)) {
167 let audio = audio.with_options(AudioOptions::auto_play().with_play_across_slides(true));
168 println!(" Format: {:?}", audio.format);
169 println!(" Auto-play: {}", audio.options.auto_play);
170 println!(" Play across slides: {}", audio.options.play_across_slides);
171 }
172
173 println!("\n=== Demo Complete ===");
174
175 Ok(())
176}14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 println!("╔════════════════════════════════════════════════════════════╗");
16 println!("║ PPTX Editing Demo ║");
17 println!("╚════════════════════════════════════════════════════════════╝\n");
18
19 // =========================================================================
20 // Step 1: Create an initial presentation
21 // =========================================================================
22 println!("📝 Step 1: Creating initial presentation...");
23
24 let initial_slides = vec![
25 SlideContent::new("Original Presentation")
26 .layout(SlideLayout::CenteredTitle)
27 .title_bold(true)
28 .title_color("1F497D"),
29
30 SlideContent::new("Slide 1: Introduction")
31 .add_bullet("This is the original content")
32 .add_bullet("Created programmatically"),
33
34 SlideContent::new("Slide 2: Features")
35 .add_bullet("Feature A")
36 .add_bullet("Feature B")
37 .add_bullet("Feature C"),
38 ];
39
40 let pptx_data = create_pptx_with_content("Original Presentation", initial_slides)?;
41 fs::write("original.pptx", &pptx_data)?;
42 println!(" ✓ Created original.pptx with 3 slides\n");
43
44 // =========================================================================
45 // Step 2: Open and inspect the presentation
46 // =========================================================================
47 println!("📖 Step 2: Opening presentation for editing...");
48
49 let mut editor = PresentationEditor::open("original.pptx")?;
50 println!(" ✓ Opened original.pptx");
51 println!(" ├── Slide count: {}", editor.slide_count());
52
53 // Read first slide
54 let slide0 = editor.get_slide(0)?;
55 println!(" └── First slide title: {:?}\n", slide0.title);
56
57 // =========================================================================
58 // Step 3: Add new slides
59 // =========================================================================
60 println!("➕ Step 3: Adding new slides...");
61
62 // Add a new slide at the end
63 let new_slide1 = SlideContent::new("New Slide: Added via Editor")
64 .add_bullet("This slide was added programmatically")
65 .add_bullet("Using PresentationEditor")
66 .add_bullet("After the presentation was created")
67 .title_color("9BBB59");
68
69 let idx1 = editor.add_slide(new_slide1)?;
70 println!(" ✓ Added slide at index {}", idx1);
71
72 // Add another slide
73 let new_slide2 = SlideContent::new("Another New Slide")
74 .layout(SlideLayout::TwoColumn)
75 .add_bullet("Left column item 1")
76 .add_bullet("Left column item 2")
77 .add_bullet("Right column item 1")
78 .add_bullet("Right column item 2");
79
80 let idx2 = editor.add_slide(new_slide2)?;
81 println!(" ✓ Added slide at index {}", idx2);
82 println!(" └── Total slides now: {}\n", editor.slide_count());
83
84 // =========================================================================
85 // Step 4: Update existing slide
86 // =========================================================================
87 println!("✏️ Step 4: Updating existing slide...");
88
89 let updated_slide = SlideContent::new("Slide 2: Updated Features")
90 .add_bullet("Feature A - Enhanced!")
91 .add_bullet("Feature B - Improved!")
92 .add_bullet("Feature C - Optimized!")
93 .add_bullet("Feature D - NEW!")
94 .title_color("C0504D")
95 .content_bold(true);
96
97 editor.update_slide(2, updated_slide)?;
98 println!(" ✓ Updated slide at index 2\n");
99
100 // =========================================================================
101 // Step 5: Save modified presentation
102 // =========================================================================
103 println!("💾 Step 5: Saving modified presentation...");
104
105 editor.save("modified.pptx")?;
106 println!(" ✓ Saved as modified.pptx\n");
107
108 // =========================================================================
109 // Step 6: Verify the changes
110 // =========================================================================
111 println!("🔍 Step 6: Verifying changes...");
112
113 let reader = PresentationReader::open("modified.pptx")?;
114 println!(" Modified presentation:");
115 println!(" ├── Slide count: {}", reader.slide_count());
116
117 for i in 0..reader.slide_count() {
118 let slide = reader.get_slide(i)?;
119 let title = slide.title.as_deref().unwrap_or("(no title)");
120 let bullets = slide.body_text.len();
121 println!(" {}── Slide {}: \"{}\" ({} bullets)",
122 if i == reader.slide_count() - 1 { "└" } else { "├" },
123 i + 1,
124 title,
125 bullets);
126 }
127
128 // =========================================================================
129 // Step 7: Demonstrate slide removal
130 // =========================================================================
131 println!("\n🗑️ Step 7: Demonstrating slide removal...");
132
133 let mut editor2 = PresentationEditor::open("modified.pptx")?;
134 println!(" Before removal: {} slides", editor2.slide_count());
135
136 // Remove the last slide
137 editor2.remove_slide(editor2.slide_count() - 1)?;
138 println!(" ✓ Removed last slide");
139 println!(" After removal: {} slides", editor2.slide_count());
140
141 editor2.save("trimmed.pptx")?;
142 println!(" ✓ Saved as trimmed.pptx");
143
144 // Cleanup
145 fs::remove_file("original.pptx").ok();
146 fs::remove_file("modified.pptx").ok();
147 fs::remove_file("trimmed.pptx").ok();
148
149 // =========================================================================
150 // Summary
151 // =========================================================================
152 println!("\n╔════════════════════════════════════════════════════════════╗");
153 println!("║ Demo Complete ║");
154 println!("╠════════════════════════════════════════════════════════════╣");
155 println!("║ Capabilities Demonstrated: ║");
156 println!("║ ✓ PresentationEditor::open() - Open for editing ║");
157 println!("║ ✓ editor.add_slide() - Add new slides ║");
158 println!("║ ✓ editor.update_slide() - Modify existing slides ║");
159 println!("║ ✓ editor.remove_slide() - Remove slides ║");
160 println!("║ ✓ editor.save() - Save modified presentation ║");
161 println!("║ ✓ editor.get_slide() - Read slide content ║");
162 println!("╚════════════════════════════════════════════════════════════╝");
163
164 Ok(())
165}13fn main() -> Result<(), Box<dyn std::error::Error>> {
14 println!("╔════════════════════════════════════════════════════════════╗");
15 println!("║ PPTX Reading & Parsing Demo ║");
16 println!("╚════════════════════════════════════════════════════════════╝\n");
17
18 // =========================================================================
19 // Step 1: Create a sample PPTX to read
20 // =========================================================================
21 println!("📝 Step 1: Creating sample presentation...");
22
23 let slides = vec![
24 SlideContent::new("Welcome to PPTX-RS")
25 .layout(SlideLayout::CenteredTitle)
26 .title_bold(true)
27 .title_color("1F497D"),
28
29 SlideContent::new("Features Overview")
30 .add_bullet("Create presentations programmatically")
31 .add_bullet("Read existing PPTX files")
32 .add_bullet("Extract text and metadata")
33 .add_bullet("Parse shapes and tables"),
34
35 SlideContent::new("Technical Details")
36 .layout(SlideLayout::TwoColumn)
37 .add_bullet("XML parsing with xml-rs")
38 .add_bullet("ZIP handling with zip crate")
39 .add_bullet("ECMA-376 compliant")
40 .add_bullet("Rust 2024 edition")
41 .add_bullet("Cross-platform")
42 .add_bullet("No external dependencies"),
43
44 SlideContent::new("Summary")
45 .add_bullet("Full read/write support")
46 .add_bullet("Comprehensive API")
47 .add_bullet("Well tested"),
48 ];
49
50 let pptx_data = create_pptx_with_content("PPTX-RS Demo", slides)?;
51 fs::write("sample_presentation.pptx", &pptx_data)?;
52 println!(" ✓ Created sample_presentation.pptx ({} bytes)\n", pptx_data.len());
53
54 // =========================================================================
55 // Step 2: Open and read the presentation
56 // =========================================================================
57 println!("📖 Step 2: Opening presentation...");
58
59 let reader = PresentationReader::open("sample_presentation.pptx")?;
60 let info = reader.info();
61
62 println!(" Presentation Info:");
63 println!(" ├── Title: {}", info.title.as_deref().unwrap_or("(none)"));
64 println!(" ├── Creator: {}", info.creator.as_deref().unwrap_or("(none)"));
65 println!(" ├── Slides: {}", info.slide_count);
66 println!(" └── Revision: {}\n", info.revision.unwrap_or(0));
67
68 // =========================================================================
69 // Step 3: Parse each slide
70 // =========================================================================
71 println!("📑 Step 3: Parsing slides...");
72
73 for i in 0..reader.slide_count() {
74 let slide = reader.get_slide(i)?;
75
76 println!("\n Slide {}:", i + 1);
77 println!(" ├── Title: {}", slide.title.as_deref().unwrap_or("(none)"));
78 println!(" ├── Shapes: {}", slide.shapes.len());
79 println!(" ├── Tables: {}", slide.tables.len());
80
81 if !slide.body_text.is_empty() {
82 println!(" └── Body text:");
83 for (j, text) in slide.body_text.iter().enumerate() {
84 let prefix = if j == slide.body_text.len() - 1 { " └──" } else { " ├──" };
85 println!("{} {}", prefix, text);
86 }
87 } else {
88 println!(" └── Body text: (none)");
89 }
90 }
91
92 // =========================================================================
93 // Step 4: Extract all text
94 // =========================================================================
95 println!("\n📋 Step 4: Extracting all text...");
96
97 let all_text = reader.extract_all_text()?;
98 println!(" Found {} text items:", all_text.len());
99 for (i, text) in all_text.iter().take(10).enumerate() {
100 println!(" {}. {}", i + 1, text);
101 }
102 if all_text.len() > 10 {
103 println!(" ... and {} more", all_text.len() - 10);
104 }
105
106 // =========================================================================
107 // Step 5: Direct XML parsing (advanced)
108 // =========================================================================
109 println!("\n🔧 Step 5: Direct XML parsing (advanced)...");
110
111 // You can also parse slide XML directly
112 let sample_xml = r#"<?xml version="1.0" encoding="UTF-8"?>
113 <p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
114 xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
115 <p:cSld>
116 <p:spTree>
117 <p:sp>
118 <p:nvSpPr>
119 <p:cNvPr id="2" name="Title"/>
120 <p:nvPr><p:ph type="title"/></p:nvPr>
121 </p:nvSpPr>
122 <p:txBody>
123 <a:p>
124 <a:r>
125 <a:rPr b="1" sz="4400"/>
126 <a:t>Direct Parse Example</a:t>
127 </a:r>
128 </a:p>
129 </p:txBody>
130 </p:sp>
131 </p:spTree>
132 </p:cSld>
133 </p:sld>"#;
134
135 let parsed = SlideParser::parse(sample_xml)?;
136 println!(" Parsed XML directly:");
137 println!(" ├── Title: {}", parsed.title.as_deref().unwrap_or("(none)"));
138 println!(" └── Shapes: {}", parsed.shapes.len());
139
140 if let Some(shape) = parsed.shapes.first() {
141 if let Some(para) = shape.paragraphs.first() {
142 if let Some(run) = para.runs.first() {
143 println!("\n Text formatting detected:");
144 println!(" ├── Bold: {}", run.bold);
145 println!(" ├── Font size: {:?}", run.font_size);
146 println!(" └── Text: {}", run.text);
147 }
148 }
149 }
150
151 // Cleanup
152 fs::remove_file("sample_presentation.pptx").ok();
153
154 // =========================================================================
155 // Summary
156 // =========================================================================
157 println!("\n╔════════════════════════════════════════════════════════════╗");
158 println!("║ Demo Complete ║");
159 println!("╠════════════════════════════════════════════════════════════╣");
160 println!("║ Capabilities Demonstrated: ║");
161 println!("║ ✓ PresentationReader::open() - Open PPTX files ║");
162 println!("║ ✓ reader.info() - Get presentation metadata ║");
163 println!("║ ✓ reader.get_slide(i) - Parse individual slides ║");
164 println!("║ ✓ reader.extract_all_text() - Extract all text ║");
165 println!("║ ✓ SlideParser::parse() - Direct XML parsing ║");
166 println!("╚════════════════════════════════════════════════════════════╝");
167
168 Ok(())
169}68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn table(self, table: Table) -> Self
pub fn table(self, table: Table) -> Self
Examples found in repository?
56fn create_simple_table_example() -> Result<(), Box<dyn std::error::Error>> {
57 let table = Table::from_data(
58 vec![
59 vec!["Name", "Age"],
60 vec!["Alice", "30"],
61 vec!["Bob", "25"],
62 ],
63 vec![2000000, 2000000],
64 500000,
65 1500000,
66 );
67
68 let slides = vec![
69 SlideContent::new("Simple 2x2 Table")
70 .add_bullet("Table with basic structure")
71 .add_bullet("Headers and data rows"),
72 SlideContent::new("Table Data")
73 .table(table),
74 ];
75
76 let pptx_data = create_pptx_with_content("Simple Table", slides)?;
77 fs::write("examples/output/simple_table.pptx", pptx_data)?;
78 Ok(())
79}
80
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}More examples
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title
6 SlideContent::new("Table Examples")
7 .add_bullet("Demonstrating table rendering in PPTX"),
8
9 // Slide 2: Simple 2x3 table
10 SlideContent::new("Employee Data")
11 .table(create_employee_table()),
12
13 // Slide 3: Styled table with colors
14 SlideContent::new("Sales Summary")
15 .table(create_sales_table()),
16
17 // Slide 4: Data table
18 SlideContent::new("Quarterly Results")
19 .table(create_quarterly_table()),
20 ];
21
22 let pptx_data = create_pptx_with_content("Table Demo", slides)?;
23 std::fs::write("table_demo.pptx", pptx_data)?;
24 println!("✓ Created table_demo.pptx with 4 slides containing tables");
25
26 Ok(())
27}3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 let slides = vec![
5 // Slide 1: Title
6 SlideContent::new("Table Text Formatting Examples")
7 .add_bullet("Demonstrating rich text content in table cells"),
8
9 // Slide 2: Text formatting examples
10 SlideContent::new("Text Formatting in Tables")
11 .table(create_text_formatting_table()),
12
13 // Slide 3: Color examples
14 SlideContent::new("Text and Background Colors")
15 .table(create_color_table()),
16
17 // Slide 4: Font examples
18 SlideContent::new("Font Size and Family")
19 .table(create_font_table()),
20
21 // Slide 5: Combined formatting
22 SlideContent::new("Combined Formatting")
23 .table(create_combined_table()),
24 ];
25
26 let pptx_data = create_pptx_with_content("Table Text Formatting", slides)?;
27 std::fs::write("examples/output/table_text_formatting.pptx", pptx_data)?;
28 println!("✓ Created table_text_formatting.pptx with rich text formatting examples");
29
30 Ok(())
31}68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn add_shape(self, shape: Shape) -> Self
pub fn add_shape(self, shape: Shape) -> Self
Add a shape to the slide
Examples found in repository?
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn with_shapes(self, shapes: Vec<Shape>) -> Self
pub fn with_shapes(self, shapes: Vec<Shape>) -> Self
Add multiple shapes to the slide
Sourcepub fn add_image(self, image: Image) -> Self
pub fn add_image(self, image: Image) -> Self
Add an image to the slide
Examples found in repository?
13fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
14 // Create output directory
15 std::fs::create_dir_all("examples/output")?;
16
17 // 1. Bullet Styles Demo
18 println!("Creating bullet styles demo...");
19
20 // Numbered list slide
21 let numbered_slide = SlideContent::new("Numbered List")
22 .with_bullet_style(BulletStyle::Number)
23 .add_bullet("First step")
24 .add_bullet("Second step")
25 .add_bullet("Third step")
26 .add_bullet("Fourth step");
27
28 // Lettered list slide
29 let lettered_slide = SlideContent::new("Lettered List")
30 .add_lettered("Option A")
31 .add_lettered("Option B")
32 .add_lettered("Option C");
33
34 // Roman numerals slide
35 let roman_slide = SlideContent::new("Roman Numerals")
36 .with_bullet_style(BulletStyle::RomanUpper)
37 .add_bullet("Chapter I")
38 .add_bullet("Chapter II")
39 .add_bullet("Chapter III");
40
41 // Mixed bullets with sub-bullets
42 let mixed_slide = SlideContent::new("Mixed Bullets")
43 .add_bullet("Main point")
44 .add_sub_bullet("Supporting detail 1")
45 .add_sub_bullet("Supporting detail 2")
46 .add_bullet("Another main point")
47 .add_sub_bullet("More details");
48
49 // Custom bullet slide
50 let custom_slide = SlideContent::new("Custom Bullets")
51 .add_styled_bullet("Star bullet", BulletStyle::Custom('★'))
52 .add_styled_bullet("Arrow bullet", BulletStyle::Custom('→'))
53 .add_styled_bullet("Check bullet", BulletStyle::Custom('✓'))
54 .add_styled_bullet("Diamond bullet", BulletStyle::Custom('◆'));
55
56 let bullet_demo = pptx!("Bullet Styles Demo")
57 .title_slide("Bullet Styles - Demonstrating various list formats")
58 .content_slide(numbered_slide)
59 .content_slide(lettered_slide)
60 .content_slide(roman_slide)
61 .content_slide(mixed_slide)
62 .content_slide(custom_slide)
63 .build()?;
64
65 std::fs::write("examples/output/bullet_styles.pptx", bullet_demo)?;
66 println!(" ✓ Created examples/output/bullet_styles.pptx");
67
68 // 2. Text Formatting Demo
69 println!("Creating text formatting demo...");
70
71 let text_demo = pptx!("Text Formatting Demo")
72 .title_slide("Text Formatting - Strikethrough, highlight, subscript, superscript")
73 .slide("Text Styles", &[
74 "Normal text for comparison",
75 "This demonstrates various formatting options",
76 "Use TextFormat for rich text styling",
77 ])
78 .slide("Font Size Presets", &[
79 &format!("TITLE: {}pt - For main titles", font_sizes::TITLE),
80 &format!("SUBTITLE: {}pt - For subtitles", font_sizes::SUBTITLE),
81 &format!("HEADING: {}pt - For section headers", font_sizes::HEADING),
82 &format!("BODY: {}pt - For regular content", font_sizes::BODY),
83 &format!("SMALL: {}pt - For smaller text", font_sizes::SMALL),
84 &format!("CAPTION: {}pt - For captions", font_sizes::CAPTION),
85 ])
86 .slide("Text Effects", &[
87 "Strikethrough: For deleted text",
88 "Highlight: For emphasized text",
89 "Subscript: H₂O style formatting",
90 "Superscript: x² style formatting",
91 ])
92 .build()?;
93
94 std::fs::write("examples/output/text_formatting.pptx", text_demo)?;
95 println!(" ✓ Created examples/output/text_formatting.pptx");
96
97 // 3. Image from Base64 Demo
98 println!("Creating image demo...");
99
100 // 1x1 red PNG pixel in base64
101 let red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
102
103 // Create image from base64
104 let img = ImageBuilder::from_base64(red_pixel_base64, inches(2.0), inches(2.0), "PNG")
105 .position(inches(4.0), inches(3.0))
106 .build();
107
108 let image_slide = SlideContent::new("Image from Base64")
109 .add_bullet("Images can be loaded from base64 encoded data")
110 .add_bullet("Useful for embedding images without file access")
111 .add_bullet("Supports PNG, JPEG, GIF formats")
112 .add_image(img);
113
114 let image_demo = pptx!("Image Features Demo")
115 .title_slide("Image Features - Loading images from various sources")
116 .content_slide(image_slide)
117 .slide("Image Sources", &[
118 "Image::new(filename) - From file path",
119 "Image::from_base64(data) - From base64 string",
120 "Image::from_bytes(data) - From raw bytes",
121 "ImageBuilder for fluent API",
122 ])
123 .build()?;
124
125 std::fs::write("examples/output/image_features.pptx", image_demo)?;
126 println!(" ✓ Created examples/output/image_features.pptx");
127
128 // 4. Theme Colors Demo
129 println!("Creating themes demo...");
130
131 let all_themes = themes::all();
132 let theme_info: Vec<String> = all_themes.iter().map(|t| {
133 format!("{}: Primary={}, Accent={}", t.name, t.primary, t.accent)
134 }).collect();
135
136 let themes_demo = pptx!("Theme Colors Demo")
137 .title_slide("Theme Colors - Predefined color palettes")
138 .slide("Available Themes", &theme_info.iter().map(|s| s.as_str()).collect::<Vec<_>>())
139 .slide("Color Constants", &[
140 &format!("Material Red: {}", colors::MATERIAL_RED),
141 &format!("Material Blue: {}", colors::MATERIAL_BLUE),
142 &format!("Material Green: {}", colors::MATERIAL_GREEN),
143 &format!("Carbon Blue 60: {}", colors::CARBON_BLUE_60),
144 &format!("Carbon Gray 100: {}", colors::CARBON_GRAY_100),
145 ])
146 .build()?;
147
148 std::fs::write("examples/output/themes_demo.pptx", themes_demo)?;
149 println!(" ✓ Created examples/output/themes_demo.pptx");
150
151 // 5. Complete Feature Showcase
152 println!("Creating complete feature showcase...");
153
154 let showcase = pptx!("ppt-rs v0.2.1 Features")
155 .title_slide("New Features in ppt-rs v0.2.1")
156 .slide("Bullet Formatting", &[
157 "BulletStyle::Number - 1, 2, 3...",
158 "BulletStyle::LetterLower/Upper - a, b, c / A, B, C",
159 "BulletStyle::RomanLower/Upper - i, ii, iii / I, II, III",
160 "BulletStyle::Custom(char) - Any custom character",
161 "Sub-bullets with indentation",
162 ])
163 .slide("Text Enhancements", &[
164 "TextFormat::strikethrough() - Strike through text",
165 "TextFormat::highlight(color) - Background highlight",
166 "TextFormat::subscript() - H₂O style",
167 "TextFormat::superscript() - x² style",
168 "font_sizes module with presets",
169 ])
170 .slide("Image Loading", &[
171 "Image::from_base64() - Base64 encoded images",
172 "Image::from_bytes() - Raw byte arrays",
173 "ImageSource enum for flexible handling",
174 "Built-in base64 decoder",
175 ])
176 .slide("Templates", &[
177 "templates::business_proposal()",
178 "templates::status_report()",
179 "templates::training_material()",
180 "templates::technical_doc()",
181 "templates::simple()",
182 ])
183 .slide("Themes & Colors", &[
184 "themes::CORPORATE, MODERN, VIBRANT, DARK",
185 "themes::NATURE, TECH, CARBON",
186 "colors module with Material Design colors",
187 "colors module with IBM Carbon colors",
188 ])
189 .build()?;
190
191 std::fs::write("examples/output/feature_showcase.pptx", showcase)?;
192 println!(" ✓ Created examples/output/feature_showcase.pptx");
193
194 println!("\n✅ All demos created successfully!");
195 println!(" Check examples/output/ for the generated files.");
196
197 Ok(())
198}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn with_images(self, images: Vec<Image>) -> Self
pub fn with_images(self, images: Vec<Image>) -> Self
Add multiple images to the slide
Sourcepub fn notes(self, notes: &str) -> Self
pub fn notes(self, notes: &str) -> Self
Add speaker notes to the slide
Examples found in repository?
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 println!("Creating test presentation with speaker notes...");
8
9 let slides = vec![
10 SlideContent::new("Slide 1 - With Notes")
11 .layout(SlideLayout::CenteredTitle)
12 .title_size(54)
13 .title_bold(true)
14 .notes("This is a speaker note for slide 1. It should appear in presenter view."),
15
16 SlideContent::new("Slide 2 - Also With Notes")
17 .add_bullet("Bullet point 1")
18 .add_bullet("Bullet point 2")
19 .add_bullet("Bullet point 3")
20 .notes("Notes for slide 2 with bullet points."),
21
22 SlideContent::new("Slide 3 - No Notes")
23 .add_bullet("This slide has no notes"),
24
25 SlideContent::new("Slide 4 - More Notes")
26 .layout(SlideLayout::TwoColumn)
27 .add_bullet("Left 1")
28 .add_bullet("Left 2")
29 .add_bullet("Right 1")
30 .add_bullet("Right 2")
31 .notes("Two column layout with speaker notes."),
32 ];
33
34 let pptx_data = create_pptx_with_content("Test Notes", slides)?;
35 fs::write("test_notes.pptx", &pptx_data)?;
36 println!("Created test_notes.pptx ({} bytes)", pptx_data.len());
37 println!("\nOpen in PowerPoint and check presenter view for notes!");
38
39 Ok(())
40}More examples
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn add_connector(self, connector: Connector) -> Self
pub fn add_connector(self, connector: Connector) -> Self
Add a connector to the slide
Examples found in repository?
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Sourcepub fn with_connectors(self, connectors: Vec<Connector>) -> Self
pub fn with_connectors(self, connectors: Vec<Connector>) -> Self
Add multiple connectors to the slide
Sourcepub fn with_videos(self, videos: Vec<Video>) -> Self
pub fn with_videos(self, videos: Vec<Video>) -> Self
Add multiple videos to the slide
Sourcepub fn with_audios(self, audios: Vec<Audio>) -> Self
pub fn with_audios(self, audios: Vec<Audio>) -> Self
Add multiple audio files to the slide
Sourcepub fn with_charts(self, charts: Vec<Chart>) -> Self
pub fn with_charts(self, charts: Vec<Chart>) -> Self
Add multiple charts to the slide
Sourcepub fn with_ink(self, ink: InkAnnotations) -> Self
pub fn with_ink(self, ink: InkAnnotations) -> Self
Add ink annotations to the slide
Sourcepub fn has_connectors(&self) -> bool
pub fn has_connectors(&self) -> bool
Check if slide has connectors
Trait Implementations§
Source§impl Clone for SlideContent
impl Clone for SlideContent
Source§fn clone(&self) -> SlideContent
fn clone(&self) -> SlideContent
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more