diff --git a/crates/engine/src/cmd/format/paragraph.rs b/crates/engine/src/cmd/format/paragraph.rs index dd88f4055..f036068f6 100644 --- a/crates/engine/src/cmd/format/paragraph.rs +++ b/crates/engine/src/cmd/format/paragraph.rs @@ -45,12 +45,17 @@ pub(super) fn bullets(s: &mut Session, p: &Value) -> Result { format_para(s, &move |para| { if on { para.props.bullet = Some(Bullet::Char { char: ch.clone() }); - para.props.bullet_font = if explicit_char { Some("Arial".into()) } else { para.props.bullet_font.clone() }; + if explicit_char { + para.props.bullet_font = Some("Arial".into()); + para.props.bullet_font_follow_text = None; + } if col.is_some() { para.props.bullet_color = col.clone(); + para.props.bullet_color_follow_text = None; } if size.is_some() { para.props.bullet_size = size; + para.props.bullet_size_follow_text = None; } if para.props.indent.is_none_or(|i| i >= 0.0) && para.props.margin_left.is_none_or(|m| m == 0.0) { para.props.margin_left = Some(18.0 + 36.0 * para.level as f64); @@ -76,9 +81,11 @@ pub(super) fn numbering(s: &mut Session, p: &Value) -> Result { para.props.bullet = Some(Bullet::AutoNum { scheme: scheme.clone(), start_at: start }); if col.is_some() { para.props.bullet_color = col.clone(); + para.props.bullet_color_follow_text = None; } if size.is_some() { para.props.bullet_size = size; + para.props.bullet_size_follow_text = None; } para.props.margin_left = Some(27.0 + 36.0 * para.level as f64); para.props.indent = Some(-27.0); diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 85cbe9d8c..dc07b2179 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -3198,6 +3198,15 @@ fn motion_path_presets_have_paths_ids_and_round_trip() { fn numbering_takes_color_and_size() { let mut s = Session::with_new(); s.execute("insert.textBox", &json!({"rect": [10, 10, 300, 100], "text": "One\nTwo"})).unwrap(); + { + let id = s.doc().unwrap().selection.shapes[0]; + let d = std::sync::Arc::make_mut(&mut s.doc_mut().unwrap().doc); + let shape = deckcraft_model::find_shape_mut(&mut std::sync::Arc::make_mut(&mut d.slides[0]).shapes, id).unwrap(); + let props = &mut shape.text.as_mut().unwrap().paragraphs[0].props; + props.bullet_font_follow_text = Some(true); + props.bullet_color_follow_text = Some(true); + props.bullet_size_follow_text = Some(true); + } s.execute("format.numbering", &json!({"on": true, "scheme": "romanUcPeriod", "start": 3, "color": "accent2", "size": 150})).unwrap(); let para = |s: &Session| { let st = s.doc().unwrap(); @@ -3207,9 +3216,13 @@ fn numbering_takes_color_and_size() { let pp = para(&s); assert!(matches!(&pp.bullet, Some(deckcraft_model::text::Bullet::AutoNum { scheme, start_at: 3 }) if scheme == "romanUcPeriod")); assert_eq!(pp.bullet_size, Some(1.5)); + assert_eq!(pp.bullet_font_follow_text, Some(true)); + assert_eq!(pp.bullet_color_follow_text, None); + assert_eq!(pp.bullet_size_follow_text, None); assert_eq!(pp.bullet_color, Some(deckcraft_model::ColorRef::scheme(deckcraft_color::SchemeSlot::Accent2))); s.execute("format.bullets", &json!({"on": true, "char": "★", "size": 9000})).unwrap(); assert_eq!(para(&s).bullet_size, Some(4.0)); + assert_eq!(para(&s).bullet_font_follow_text, None); } #[test] diff --git a/crates/model/src/text.rs b/crates/model/src/text.rs index 1c70e397e..362f43939 100644 --- a/crates/model/src/text.rs +++ b/crates/model/src/text.rs @@ -266,14 +266,35 @@ impl ParaProps { if self.bullet.is_none() { self.bullet.clone_from(&p.bullet); } + if self.bullet_font_follow_text == Some(false) || self.bullet_font.is_some() { + self.bullet_font_follow_text = None; + } if self.bullet_font.is_none() && self.bullet_font_follow_text.is_none() { - self.bullet_font.clone_from(&p.bullet_font); + if p.bullet_font_follow_text == Some(true) { + self.bullet_font_follow_text = Some(true); + } else { + self.bullet_font.clone_from(&p.bullet_font); + } + } + if self.bullet_color_follow_text == Some(false) || self.bullet_color.is_some() { + self.bullet_color_follow_text = None; } if self.bullet_color.is_none() && self.bullet_color_follow_text.is_none() { - self.bullet_color.clone_from(&p.bullet_color); + if p.bullet_color_follow_text == Some(true) { + self.bullet_color_follow_text = Some(true); + } else { + self.bullet_color.clone_from(&p.bullet_color); + } } - if self.bullet_size_follow_text.is_none() { - self.bullet_size = self.bullet_size.or(p.bullet_size); + if self.bullet_size_follow_text == Some(false) || self.bullet_size.is_some() { + self.bullet_size_follow_text = None; + } + if self.bullet_size.is_none() && self.bullet_size_follow_text.is_none() { + if p.bullet_size_follow_text == Some(true) { + self.bullet_size_follow_text = Some(true); + } else { + self.bullet_size = p.bullet_size; + } } if self.tabs.is_none() { self.tabs.clone_from(&p.tabs); @@ -663,5 +684,27 @@ mod tests { assert_eq!(child.bullet_font, None); assert_eq!(child.bullet_color, None); assert_eq!(child.bullet_size, None); + + let mut inherited_reset = ParaProps::default(); + inherited_reset.inherit(&ParaProps { + bullet_font_follow_text: Some(true), + bullet_color_follow_text: Some(true), + bullet_size_follow_text: Some(true), + ..Default::default() + }); + assert_eq!(inherited_reset.bullet_font_follow_text, Some(true)); + assert_eq!(inherited_reset.bullet_color_follow_text, Some(true)); + assert_eq!(inherited_reset.bullet_size_follow_text, Some(true)); + + let mut explicit_false = ParaProps { + bullet_font_follow_text: Some(false), + bullet_color_follow_text: Some(false), + bullet_size_follow_text: Some(false), + ..Default::default() + }; + explicit_false.inherit(&parent); + assert_eq!(explicit_false.bullet_font, parent.bullet_font); + assert_eq!(explicit_false.bullet_color, parent.bullet_color); + assert_eq!(explicit_false.bullet_size, parent.bullet_size); } }