Skip to main content

umya_spreadsheet/structs/drawing/
theme.rs

1use std::io::Cursor;
2
3use quick_xml::{
4    Reader,
5    Writer,
6    events::{
7        BytesStart,
8        Event,
9    },
10};
11
12use super::{
13    super::StringValue,
14    EffectList,
15    EffectStyle,
16    GradientFill,
17    GradientStop,
18    LinearGradientFill,
19    Miter,
20    OuterShadow,
21    Outline,
22    PenAlignmentValues,
23    PercentageType,
24    PositiveFixedPercentageType,
25    PresetDash,
26    PresetLineDashValues,
27    RgbColorModelHex,
28    SchemeColor,
29    SchemeColorValues,
30    SolidFill,
31    SystemColor,
32    SystemColorValues,
33    ThemeElements,
34};
35use crate::{
36    helper::const_str::DRAWINGML_MAIN_NS,
37    reader::driver::{
38        get_attribute,
39        xml_read_loop,
40    },
41    writer::driver::{
42        write_end_tag,
43        write_start_tag,
44    },
45};
46
47#[derive(Clone, Default, Debug)]
48pub struct Theme {
49    name:           StringValue,
50    theme_elements: ThemeElements,
51}
52
53impl Theme {
54    #[inline]
55    #[must_use]
56    pub fn name(&self) -> &str {
57        self.name.value_str()
58    }
59
60    #[inline]
61    #[must_use]
62    #[deprecated(since = "3.0.0", note = "Use name()")]
63    pub fn get_name(&self) -> &str {
64        self.name()
65    }
66
67    #[inline]
68    pub fn set_name<S: Into<String>>(&mut self, value: S) -> &mut Self {
69        self.name.set_value(value);
70        self
71    }
72
73    #[inline]
74    #[must_use]
75    pub fn theme_elements(&self) -> &ThemeElements {
76        &self.theme_elements
77    }
78
79    #[inline]
80    #[must_use]
81    #[deprecated(since = "3.0.0", note = "Use theme_elements()")]
82    pub fn get_theme_elements(&self) -> &ThemeElements {
83        self.theme_elements()
84    }
85
86    #[inline]
87    pub fn theme_elements_mut(&mut self) -> &mut ThemeElements {
88        &mut self.theme_elements
89    }
90
91    #[inline]
92    #[deprecated(since = "3.0.0", note = "Use theme_elements_mut()")]
93    pub fn get_theme_elements_mut(&mut self) -> &mut ThemeElements {
94        self.theme_elements_mut()
95    }
96
97    #[inline]
98    pub fn set_theme_elements(&mut self, value: ThemeElements) -> &mut Self {
99        self.theme_elements = value;
100        self
101    }
102
103    pub(crate) fn default_value() -> Theme {
104        let mut def = Theme::default();
105        def.set_name("Office Theme");
106
107        // color_scheme
108        def.theme_elements_mut()
109            .color_scheme_mut()
110            .set_name("Office");
111
112        let mut dk1 = SystemColor::default();
113        dk1.set_val(SystemColorValues::WindowText);
114        dk1.set_last_color("000000");
115        def.theme_elements_mut()
116            .color_scheme_mut()
117            .dk1_mut()
118            .set_system_color(dk1); // dk1
119
120        let mut lt1 = SystemColor::default();
121        lt1.set_val(SystemColorValues::Window);
122        lt1.set_last_color("FFFFFF");
123        def.theme_elements_mut()
124            .color_scheme_mut()
125            .lt1_mut()
126            .set_system_color(lt1); // lt1
127
128        let mut dk2 = RgbColorModelHex::default();
129        dk2.set_val("44546A");
130        def.theme_elements_mut()
131            .color_scheme_mut()
132            .dk2_mut()
133            .set_rgb_color_model_hex(dk2); // dk2
134
135        let mut lt2 = RgbColorModelHex::default();
136        lt2.set_val("E7E6E6");
137        def.theme_elements_mut()
138            .color_scheme_mut()
139            .lt2_mut()
140            .set_rgb_color_model_hex(lt2); // lt2
141
142        let mut accent1 = RgbColorModelHex::default();
143        accent1.set_val("4472C4");
144        def.theme_elements_mut()
145            .color_scheme_mut()
146            .accent1_mut()
147            .set_rgb_color_model_hex(accent1); // accent1
148
149        let mut accent2 = RgbColorModelHex::default();
150        accent2.set_val("ED7D31");
151        def.theme_elements_mut()
152            .color_scheme_mut()
153            .accent2_mut()
154            .set_rgb_color_model_hex(accent2); // accent2
155
156        let mut accent3 = RgbColorModelHex::default();
157        accent3.set_val("A5A5A5");
158        def.theme_elements_mut()
159            .color_scheme_mut()
160            .accent3_mut()
161            .set_rgb_color_model_hex(accent3); // accent3
162
163        let mut accent4 = RgbColorModelHex::default();
164        accent4.set_val("FFC000");
165        def.theme_elements_mut()
166            .color_scheme_mut()
167            .accent4_mut()
168            .set_rgb_color_model_hex(accent4); // accent4
169
170        let mut accent5 = RgbColorModelHex::default();
171        accent5.set_val("5B9BD5");
172        def.theme_elements_mut()
173            .color_scheme_mut()
174            .accent5_mut()
175            .set_rgb_color_model_hex(accent5); // accent5
176
177        let mut accent6 = RgbColorModelHex::default();
178        accent6.set_val("70AD47");
179        def.theme_elements_mut()
180            .color_scheme_mut()
181            .accent6_mut()
182            .set_rgb_color_model_hex(accent6); // accent6
183
184        let mut hlink = RgbColorModelHex::default();
185        hlink.set_val("0563C1");
186        def.theme_elements_mut()
187            .color_scheme_mut()
188            .hlink_mut()
189            .set_rgb_color_model_hex(hlink); // hlink
190
191        let mut fol_hlink = RgbColorModelHex::default();
192        fol_hlink.set_val("954F72");
193        def.theme_elements_mut()
194            .color_scheme_mut()
195            .fol_hlink_mut()
196            .set_rgb_color_model_hex(fol_hlink); // folHlink
197
198        // font_scheme
199        def.theme_elements_mut()
200            .font_scheme_mut()
201            .set_name("Office");
202
203        def.theme_elements_mut()
204            .font_scheme_mut()
205            .major_font_mut()
206            .set_defalut_value_major();
207
208        def.theme_elements_mut()
209            .font_scheme_mut()
210            .minor_font_mut()
211            .set_defalut_value_minor();
212
213        // format_scheme
214        def.theme_elements_mut()
215            .format_scheme_mut()
216            .set_name("Office");
217
218        let mut solid_fill = SolidFill::default();
219        let mut scheme_color = SchemeColor::default();
220        scheme_color.set_val(SchemeColorValues::PhColor);
221        solid_fill.set_scheme_color(scheme_color);
222        def.theme_elements_mut()
223            .format_scheme_mut()
224            .fill_style_list_mut()
225            .add_solid_fill(solid_fill);
226
227        let mut gradient_fill = GradientFill::default();
228        gradient_fill.set_rotate_with_shape(true);
229        //
230        let mut gradient_stop = GradientStop::default();
231        gradient_stop.set_position(0);
232        let mut scheme_color = SchemeColor::default();
233        scheme_color.set_val(SchemeColorValues::PhColor);
234        let mut lum_mod = PercentageType::default();
235        lum_mod.set_val(110_000);
236        scheme_color.set_luminance_modulation(lum_mod);
237        let mut sat_mod = PercentageType::default();
238        sat_mod.set_val(105_000);
239        scheme_color.set_saturation_modulation(sat_mod);
240        let mut tint = PositiveFixedPercentageType::default();
241        tint.set_val(67_000);
242        scheme_color.set_tint(tint);
243        gradient_stop.set_scheme_color(scheme_color);
244        gradient_fill
245            .gradient_stop_list_mut()
246            .add_gradient_stop(gradient_stop);
247        //
248        let mut gradient_stop = GradientStop::default();
249        gradient_stop.set_position(50_000);
250        let mut scheme_color = SchemeColor::default();
251        scheme_color.set_val(SchemeColorValues::PhColor);
252        let mut lum_mod = PercentageType::default();
253        lum_mod.set_val(105_000);
254        scheme_color.set_luminance_modulation(lum_mod);
255        let mut sat_mod = PercentageType::default();
256        sat_mod.set_val(103_000);
257        scheme_color.set_saturation_modulation(sat_mod);
258        let mut tint = PositiveFixedPercentageType::default();
259        tint.set_val(73000);
260        scheme_color.set_tint(tint);
261        gradient_stop.set_scheme_color(scheme_color);
262        gradient_fill
263            .gradient_stop_list_mut()
264            .add_gradient_stop(gradient_stop);
265        //
266        let mut gradient_stop = GradientStop::default();
267        gradient_stop.set_position(100_000);
268        let mut scheme_color = SchemeColor::default();
269        scheme_color.set_val(SchemeColorValues::PhColor);
270        let mut lum_mod = PercentageType::default();
271        lum_mod.set_val(105_000);
272        scheme_color.set_luminance_modulation(lum_mod);
273        let mut sat_mod = PercentageType::default();
274        sat_mod.set_val(109_000);
275        scheme_color.set_saturation_modulation(sat_mod);
276        let mut tint = PositiveFixedPercentageType::default();
277        tint.set_val(81000);
278        scheme_color.set_tint(tint);
279        gradient_stop.set_scheme_color(scheme_color);
280        gradient_fill
281            .gradient_stop_list_mut()
282            .add_gradient_stop(gradient_stop);
283        //
284        let mut linear_gradient_fill = LinearGradientFill::default();
285        linear_gradient_fill.set_angle(5_400_000);
286        linear_gradient_fill.set_scaled(false);
287        gradient_fill.set_linear_gradient_fill(linear_gradient_fill);
288        //
289        def.theme_elements_mut()
290            .format_scheme_mut()
291            .fill_style_list_mut()
292            .add_gradient_fill_collection(gradient_fill);
293
294        let mut gradient_fill = GradientFill::default();
295        gradient_fill.set_rotate_with_shape(true);
296        //
297        let mut gradient_stop = GradientStop::default();
298        gradient_stop.set_position(0);
299        let mut scheme_color = SchemeColor::default();
300        scheme_color.set_val(SchemeColorValues::PhColor);
301        let mut tint = PositiveFixedPercentageType::default();
302        tint.set_val(94000);
303        scheme_color.set_tint(tint);
304        let mut sat_mod = PercentageType::default();
305        sat_mod.set_val(103_000);
306        scheme_color.set_saturation_modulation(sat_mod);
307        let mut lum_mod = PercentageType::default();
308        lum_mod.set_val(102_000);
309        scheme_color.set_luminance_modulation(lum_mod);
310        gradient_stop.set_scheme_color(scheme_color);
311        gradient_fill
312            .gradient_stop_list_mut()
313            .add_gradient_stop(gradient_stop);
314        //
315        let mut gradient_stop = GradientStop::default();
316        gradient_stop.set_position(50_000);
317        let mut scheme_color = SchemeColor::default();
318        scheme_color.set_val(SchemeColorValues::PhColor);
319        let mut sat_mod = PercentageType::default();
320        sat_mod.set_val(110_000);
321        scheme_color.set_saturation_modulation(sat_mod);
322        let mut shade = PositiveFixedPercentageType::default();
323        shade.set_val(100_000);
324        scheme_color.set_shade(shade);
325        let mut lum_mod = PercentageType::default();
326        lum_mod.set_val(100_000);
327        scheme_color.set_luminance_modulation(lum_mod);
328        gradient_stop.set_scheme_color(scheme_color);
329        gradient_fill
330            .gradient_stop_list_mut()
331            .add_gradient_stop(gradient_stop);
332        //
333        let mut gradient_stop = GradientStop::default();
334        gradient_stop.set_position(100_000);
335        let mut scheme_color = SchemeColor::default();
336        scheme_color.set_val(SchemeColorValues::PhColor);
337        let mut shade = PositiveFixedPercentageType::default();
338        shade.set_val(78_000);
339        scheme_color.set_shade(shade);
340        let mut sat_mod = PercentageType::default();
341        sat_mod.set_val(120_000);
342        scheme_color.set_saturation_modulation(sat_mod);
343        let mut lum_mod = PercentageType::default();
344        lum_mod.set_val(99000);
345        scheme_color.set_luminance_modulation(lum_mod);
346        gradient_stop.set_scheme_color(scheme_color);
347        gradient_fill
348            .gradient_stop_list_mut()
349            .add_gradient_stop(gradient_stop);
350        //
351        let mut linear_gradient_fill = LinearGradientFill::default();
352        linear_gradient_fill.set_angle(5_400_000);
353        linear_gradient_fill.set_scaled(false);
354        gradient_fill.set_linear_gradient_fill(linear_gradient_fill);
355        //
356        def.theme_elements_mut()
357            .format_scheme_mut()
358            .fill_style_list_mut()
359            .add_gradient_fill_collection(gradient_fill);
360
361        let mut outline = Outline::default();
362        outline.set_width(6350);
363        outline.set_cap_type("flat");
364        outline.set_compound_line_type("sng");
365        outline.set_alignment(PenAlignmentValues::Center);
366        //
367        let mut solid_fill = SolidFill::default();
368        let mut scheme_color = SchemeColor::default();
369        scheme_color.set_val(SchemeColorValues::PhColor);
370        solid_fill.set_scheme_color(scheme_color);
371        outline.set_solid_fill(solid_fill);
372        //
373        let mut preset_dash = PresetDash::default();
374        preset_dash.set_val(PresetLineDashValues::Solid);
375        outline.set_preset_dash(preset_dash);
376        //
377        let mut miter = Miter::default();
378        miter.set_limit(800_000);
379        outline.set_miter(miter);
380        //
381        def.theme_elements_mut()
382            .format_scheme_mut()
383            .line_style_list_mut()
384            .add_outline_collection(outline);
385
386        let mut outline = Outline::default();
387        outline.set_width(12700);
388        outline.set_cap_type("flat");
389        outline.set_compound_line_type("sng");
390        outline.set_alignment(PenAlignmentValues::Center);
391        //
392        let mut solid_fill = SolidFill::default();
393        let mut scheme_color = SchemeColor::default();
394        scheme_color.set_val(SchemeColorValues::PhColor);
395        solid_fill.set_scheme_color(scheme_color);
396        outline.set_solid_fill(solid_fill);
397        //
398        let mut preset_dash = PresetDash::default();
399        preset_dash.set_val(PresetLineDashValues::Solid);
400        outline.set_preset_dash(preset_dash);
401        //
402        let mut miter = Miter::default();
403        miter.set_limit(800_000);
404        outline.set_miter(miter);
405        //
406        def.theme_elements_mut()
407            .format_scheme_mut()
408            .line_style_list_mut()
409            .add_outline_collection(outline);
410
411        let mut outline = Outline::default();
412        outline.set_width(19050);
413        outline.set_cap_type("flat");
414        outline.set_compound_line_type("sng");
415        outline.set_alignment(PenAlignmentValues::Center);
416        //
417        let mut solid_fill = SolidFill::default();
418        let mut scheme_color = SchemeColor::default();
419        scheme_color.set_val(SchemeColorValues::PhColor);
420        solid_fill.set_scheme_color(scheme_color);
421        outline.set_solid_fill(solid_fill);
422        //
423        let mut preset_dash = PresetDash::default();
424        preset_dash.set_val(PresetLineDashValues::Solid);
425        outline.set_preset_dash(preset_dash);
426        //
427        let mut miter = Miter::default();
428        miter.set_limit(800_000);
429        outline.set_miter(miter);
430        //
431        def.theme_elements_mut()
432            .format_scheme_mut()
433            .line_style_list_mut()
434            .add_outline_collection(outline);
435
436        let mut effect_style = EffectStyle::default();
437        let effect_list = EffectList::default();
438        effect_style.set_effect_list(effect_list);
439        def.theme_elements_mut()
440            .format_scheme_mut()
441            .effect_style_list_mut()
442            .add_effect_style_collection(effect_style);
443
444        let mut effect_style = EffectStyle::default();
445        let effect_list = EffectList::default();
446        effect_style.set_effect_list(effect_list);
447        def.theme_elements_mut()
448            .format_scheme_mut()
449            .effect_style_list_mut()
450            .add_effect_style_collection(effect_style);
451
452        let mut effect_style = EffectStyle::default();
453        let mut effect_list = EffectList::default();
454        let mut outer_shadow = OuterShadow::default();
455        outer_shadow.set_blur_radius("57150");
456        outer_shadow.set_distance("19050");
457        outer_shadow.set_direction("5400000");
458        outer_shadow.set_alignment("ctr");
459        outer_shadow.set_rotate_with_shape("0");
460        let mut srgb_clr = RgbColorModelHex::default();
461        srgb_clr.set_val("000000");
462        let mut alpha = PositiveFixedPercentageType::default();
463        alpha.set_val(63000);
464        srgb_clr.set_alpha(alpha);
465        outer_shadow.set_rgb_color_model_hex(srgb_clr);
466        effect_list.set_outer_shadow(outer_shadow);
467        effect_style.set_effect_list(effect_list);
468        def.theme_elements_mut()
469            .format_scheme_mut()
470            .effect_style_list_mut()
471            .add_effect_style_collection(effect_style);
472
473        let mut solid_fill = SolidFill::default();
474        let mut scheme_color = SchemeColor::default();
475        scheme_color.set_val(SchemeColorValues::PhColor);
476        solid_fill.set_scheme_color(scheme_color);
477        def.theme_elements_mut()
478            .format_scheme_mut()
479            .background_fill_style_list_mut()
480            .add_solid_fill(solid_fill);
481        //
482        let mut solid_fill = SolidFill::default();
483        let mut scheme_color = SchemeColor::default();
484        scheme_color.set_val(SchemeColorValues::PhColor);
485        let mut sat_mod = PercentageType::default();
486        sat_mod.set_val(170_000);
487        scheme_color.set_saturation_modulation(sat_mod);
488        let mut tint = PositiveFixedPercentageType::default();
489        tint.set_val(95000);
490        scheme_color.set_tint(tint);
491        solid_fill.set_scheme_color(scheme_color);
492        def.theme_elements_mut()
493            .format_scheme_mut()
494            .background_fill_style_list_mut()
495            .add_solid_fill(solid_fill);
496
497        let mut gradient_fill = GradientFill::default();
498        gradient_fill.set_rotate_with_shape(true);
499        //
500        let mut gradient_stop = GradientStop::default();
501        gradient_stop.set_position(0);
502        let mut scheme_color = SchemeColor::default();
503        scheme_color.set_val(SchemeColorValues::PhColor);
504        let mut tint = PositiveFixedPercentageType::default();
505        tint.set_val(93000);
506        scheme_color.set_tint(tint);
507        let mut shade = PositiveFixedPercentageType::default();
508        shade.set_val(98_000);
509        scheme_color.set_shade(shade);
510        let mut sat_mod = PercentageType::default();
511        sat_mod.set_val(150_000);
512        scheme_color.set_saturation_modulation(sat_mod);
513        let mut lum_mod = PercentageType::default();
514        lum_mod.set_val(102_000);
515        scheme_color.set_luminance_modulation(lum_mod);
516        gradient_stop.set_scheme_color(scheme_color);
517        gradient_fill
518            .gradient_stop_list_mut()
519            .add_gradient_stop(gradient_stop);
520        //
521        let mut gradient_stop = GradientStop::default();
522        gradient_stop.set_position(50_000);
523        let mut scheme_color = SchemeColor::default();
524        scheme_color.set_val(SchemeColorValues::PhColor);
525        let mut tint = PositiveFixedPercentageType::default();
526        tint.set_val(98_000);
527        scheme_color.set_tint(tint);
528        let mut sat_mod = PercentageType::default();
529        sat_mod.set_val(130_000);
530        scheme_color.set_saturation_modulation(sat_mod);
531        let mut shade = PositiveFixedPercentageType::default();
532        shade.set_val(90_000);
533        scheme_color.set_shade(shade);
534        let mut lum_mod = PercentageType::default();
535        lum_mod.set_val(103_000);
536        scheme_color.set_luminance_modulation(lum_mod);
537        gradient_stop.set_scheme_color(scheme_color);
538        gradient_fill
539            .gradient_stop_list_mut()
540            .add_gradient_stop(gradient_stop);
541        //
542        let mut gradient_stop = GradientStop::default();
543        gradient_stop.set_position(100_000);
544        let mut scheme_color = SchemeColor::default();
545        scheme_color.set_val(SchemeColorValues::PhColor);
546        let mut shade = PositiveFixedPercentageType::default();
547        shade.set_val(63000);
548        scheme_color.set_shade(shade);
549        let mut sat_mod = PercentageType::default();
550        sat_mod.set_val(120_000);
551        scheme_color.set_saturation_modulation(sat_mod);
552        gradient_stop.set_scheme_color(scheme_color);
553        gradient_fill
554            .gradient_stop_list_mut()
555            .add_gradient_stop(gradient_stop);
556        //
557        let mut linear_gradient_fill = LinearGradientFill::default();
558        linear_gradient_fill.set_angle(5_400_000);
559        linear_gradient_fill.set_scaled(false);
560        gradient_fill.set_linear_gradient_fill(linear_gradient_fill);
561        //
562        def.theme_elements_mut()
563            .format_scheme_mut()
564            .background_fill_style_list_mut()
565            .add_gradient_fill_collection(gradient_fill);
566
567        def
568    }
569
570    #[deprecated(since = "3.0.0", note = "Use default_value()")]
571    pub(crate) fn get_default_value() -> Theme {
572        Self::default_value()
573    }
574
575    pub(crate) fn set_attributes<R: std::io::BufRead>(
576        &mut self,
577        reader: &mut Reader<R>,
578        e: &BytesStart,
579    ) {
580        if let Some(v) = get_attribute(e, b"name") {
581            self.name.set_value(v);
582        }
583
584        xml_read_loop!(
585            reader,
586            Event::Start(ref e) => {
587                if e.name().into_inner() == b"a:themeElements" {
588                    self.theme_elements.set_attributes(reader, e);
589                }
590            },
591            Event::End(ref e) => {
592                if e.name().into_inner() == b"a:theme" {
593                    return
594                }
595            },
596            Event::Eof => panic!("Error: Could not find {} end element", "a:theme")
597        );
598    }
599
600    pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
601        // a:theme
602        let mut attributes: crate::structs::AttrCollection = Vec::new();
603        attributes.push(("xmlns:a", DRAWINGML_MAIN_NS).into());
604        if self.name.has_value() {
605            attributes.push(("name", self.name.value_str()).into());
606        }
607        write_start_tag(writer, "a:theme", attributes, false);
608
609        // a:themeElements
610        self.theme_elements.write_to(writer);
611
612        // a:objectDefaults
613        write_start_tag(writer, "a:objectDefaults", vec![], true);
614
615        // a:extraClrSchemeLst
616        write_start_tag(writer, "a:extraClrSchemeLst", vec![], true);
617
618        write_end_tag(writer, "a:theme");
619    }
620}