mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-03 00:41:28 -06:00
Slide Size: choose Portrait or Landscape (#198)
The Slide Size dialog gets an Orientation choice that swaps width and height, and design.slideSize takes orientation: portrait|landscape so a preset can be made portrait from the CLI and MCP too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0ec0cc5e81
commit
1601fd250a
@@ -33,7 +33,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Slide Size",
|
||||
["Design", "Customize"],
|
||||
None,
|
||||
"{preset?: widescreen|standard|… | w, h: pt, scale?: maximize|ensureFit|none}",
|
||||
"{preset?: widescreen|standard|… | w, h: pt, orientation?: portrait|landscape, scale?: maximize|ensureFit|none}",
|
||||
has_doc,
|
||||
slide_size
|
||||
),
|
||||
@@ -251,6 +251,12 @@ fn slide_size(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
f64_param(p, "h").ok_or_else(|| bad("design.slideSize", "missing `h`"))?.clamp(72.0, 4032.0),
|
||||
)
|
||||
};
|
||||
let size = match str_param(p, "orientation") {
|
||||
Some("portrait") if size.width > size.height => Size::new(size.height, size.width),
|
||||
Some("landscape") if size.height > size.width => Size::new(size.height, size.width),
|
||||
Some("portrait" | "landscape") | None => size,
|
||||
Some(o) => return Err(bad("design.slideSize", format!("unknown orientation `{o}`"))),
|
||||
};
|
||||
let mode = str_param(p, "scale").unwrap_or("ensureFit").to_string();
|
||||
s.edit(|doc, _| {
|
||||
let old = doc.slide_size;
|
||||
|
||||
@@ -244,6 +244,11 @@ fn themes_and_slide_size() {
|
||||
assert_eq!(s.doc().unwrap().doc.masters[0].theme.name, "Ember");
|
||||
s.execute("design.slideSize", &json!({"preset": "standard"})).unwrap();
|
||||
assert_eq!(s.doc().unwrap().doc.slide_size.width, 720.0);
|
||||
s.execute("design.slideSize", &json!({"preset": "widescreen", "orientation": "portrait"})).unwrap();
|
||||
assert_eq!((s.doc().unwrap().doc.slide_size.width, s.doc().unwrap().doc.slide_size.height), (540.0, 960.0));
|
||||
s.execute("design.slideSize", &json!({"w": 540.0, "h": 960.0, "orientation": "landscape"})).unwrap();
|
||||
assert_eq!((s.doc().unwrap().doc.slide_size.width, s.doc().unwrap().doc.slide_size.height), (960.0, 540.0));
|
||||
assert!(s.execute("design.slideSize", &json!({"preset": "standard", "orientation": "sideways"})).is_err());
|
||||
s.execute("design.headerFooter", &json!({"slideNumber": true, "footer": true, "footerText": "Hello"})).unwrap();
|
||||
let v = s.execute("slide.inspect", &json!({})).unwrap();
|
||||
assert!(v["shapes"].as_array().unwrap().iter().any(|x| x["placeholder"] == "sldNum"));
|
||||
|
||||
@@ -148,6 +148,17 @@ fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool {
|
||||
});
|
||||
field(ui, d, "Width (in):", "w", &format!("{:.2}", cur.width / 72.0));
|
||||
field(ui, d, "Height (in):", "h", &format!("{:.2}", cur.height / 72.0));
|
||||
let (w, h) = (num(d, "w", cur.width / 72.0), num(d, "h", cur.height / 72.0));
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Orientation:");
|
||||
let portrait = ui.radio(h > w, "Portrait").clicked();
|
||||
let landscape = ui.radio(w >= h, "Landscape").clicked();
|
||||
// Picking the other orientation swaps the width and height fields.
|
||||
if portrait && w > h || landscape && h > w {
|
||||
d.fields.insert("w".into(), format!("{h:.2}"));
|
||||
d.fields.insert("h".into(), format!("{w:.2}"));
|
||||
}
|
||||
});
|
||||
let maximize = check(ui, d, "Maximize content (else ensure fit)", "max", false);
|
||||
let (ok, cancel) = buttons(ui, "OK");
|
||||
if ok {
|
||||
|
||||
Reference in New Issue
Block a user