mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-31 22:16:59 -06:00
Merge PR #500 from NikitkaRa: Format Shape: line compound, cap, join, arrows and sizes; lock aspect ratio
# Conflicts: # crates/engine/src/tests.rs
This commit is contained in:
@@ -51,7 +51,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Shape Outline",
|
||||
["Shape Format", "Shape Styles"],
|
||||
None,
|
||||
"{color?, none?, width?: pt, dash?: solid|dot|dash|lgDash|dashDot|sysDot|sysDash, cap?, join?, head?: none|triangle|stealth|diamond|oval|arrow, tail?, reset?, ids?}",
|
||||
"{color?, none?, width?: pt, dash?: solid|dot|dash|lgDash|dashDot|sysDot|sysDash, cap?: flat|round|square, join?: round|bevel|miter, compound?: single|double|thickThin|thinThick|triple, head?: none|triangle|stealth|diamond|oval|arrow, tail?, headSize?: sm|med|lg, tailSize?, reset?, ids?}",
|
||||
has_selection,
|
||||
line
|
||||
),
|
||||
@@ -350,6 +350,15 @@ fn line(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
"square" => deckcraft_model::style::LineCap::Square,
|
||||
_ => deckcraft_model::style::LineCap::Flat,
|
||||
});
|
||||
let compound = str_param(p, "compound").map(|c| match c {
|
||||
"double" => deckcraft_model::style::Compound::Double,
|
||||
"thickThin" => deckcraft_model::style::Compound::ThickThin,
|
||||
"thinThick" => deckcraft_model::style::Compound::ThinThick,
|
||||
"triple" => deckcraft_model::style::Compound::Triple,
|
||||
_ => deckcraft_model::style::Compound::Single,
|
||||
});
|
||||
let end_size = |k: &str| str_param(p, k).filter(|v| matches!(*v, "sm" | "med" | "lg")).map(str::to_string);
|
||||
let (head_size, tail_size) = (end_size("headSize"), end_size("tailSize"));
|
||||
let join = str_param(p, "join").map(|c| match c {
|
||||
"bevel" => deckcraft_model::style::LineJoin::Bevel,
|
||||
"miter" => deckcraft_model::style::LineJoin::Miter,
|
||||
@@ -376,11 +385,20 @@ fn line(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if dash.is_some() {
|
||||
l.dash.clone_from(&dash);
|
||||
}
|
||||
let keep_size = |old: &Option<LineEnd>, new: &Option<LineEnd>| {
|
||||
new.clone().map(|mut n| {
|
||||
if let Some(o) = old {
|
||||
n.w.clone_from(&o.w);
|
||||
n.len.clone_from(&o.len);
|
||||
}
|
||||
n
|
||||
})
|
||||
};
|
||||
if let Some(h) = &head {
|
||||
l.head.clone_from(h);
|
||||
l.head = keep_size(&l.head, h);
|
||||
}
|
||||
if let Some(t) = &tail {
|
||||
l.tail.clone_from(t);
|
||||
l.tail = keep_size(&l.tail, t);
|
||||
}
|
||||
if cap.is_some() {
|
||||
l.cap = cap;
|
||||
@@ -388,6 +406,16 @@ fn line(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if join.is_some() {
|
||||
l.join = join;
|
||||
}
|
||||
if compound.is_some() {
|
||||
l.compound = compound;
|
||||
}
|
||||
// Arrowhead size (width and length together), kept when the kind changes.
|
||||
for (end, size) in [(&mut l.head, &head_size), (&mut l.tail, &tail_size)] {
|
||||
if let (Some(e), Some(sz)) = (end.as_mut(), size) {
|
||||
e.w.clone_from(sz);
|
||||
e.len.clone_from(sz);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1207,3 +1207,27 @@ fn pdf_options_take_paper_and_orientation() {
|
||||
assert!(cmd::file::pdf_options(&json!({"paper": "tabloid"}), 1).is_err());
|
||||
assert!(cmd::file::pdf_options(&json!({"orientation": "sideways"}), 1).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_line_sets_compound_and_arrow_sizes() {
|
||||
// The Format Shape pane's Line page: compound type, arrowheads and their sizes.
|
||||
use deckcraft_model::style::Compound;
|
||||
let mut s = Session::with_new();
|
||||
s.execute("slide.new", &json!({"layout": "blank"})).unwrap();
|
||||
s.execute("shape.insert", &json!({"preset": "line", "rect": [100, 100, 200, 0]})).unwrap();
|
||||
s.execute("shape.line", &json!({"compound": "thickThin", "head": "oval", "tail": "triangle", "tailSize": "lg"})).unwrap();
|
||||
let line = |s: &Session| s.doc().unwrap().selected_shapes()[0].line.clone().unwrap();
|
||||
let l = line(&s);
|
||||
assert_eq!(l.compound, Some(Compound::ThickThin));
|
||||
assert_eq!(l.head.as_ref().map(|e| (e.kind.as_str(), e.w.as_str())), Some(("oval", "med")));
|
||||
assert_eq!(l.tail.as_ref().map(|e| (e.kind.as_str(), e.w.as_str(), e.len.as_str())), Some(("triangle", "lg", "lg")));
|
||||
// Changing the arrow keeps its size; an unknown size is ignored; "none" removes it.
|
||||
s.execute("shape.line", &json!({"tail": "stealth", "headSize": "huge"})).unwrap();
|
||||
let l = line(&s);
|
||||
assert_eq!(l.tail.as_ref().map(|e| (e.kind.as_str(), e.w.as_str())), Some(("stealth", "lg")));
|
||||
assert_eq!(l.head.as_ref().map(|e| e.w.as_str()), Some("med"));
|
||||
s.execute("shape.line", &json!({"head": "none", "compound": "single"})).unwrap();
|
||||
let l = line(&s);
|
||||
assert!(l.head.is_none());
|
||||
assert_eq!(l.compound, Some(Compound::Single));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user