Merge PR #1063: UI: Typography opens with its named panel groups and a clear page

Conflicts:
- docs/ui-parity.md: kept both paragraphs.
This commit is contained in:
aiongg
2026-10-16 04:03:29 +00:00
3 changed files with 51 additions and 5 deletions
+2
View File
@@ -355,6 +355,8 @@ list) · [roadmap.md](docs/roadmap.md) (milestones, plan) · [parity-checklist.m
Style Options; Cancel restores the document and OK records one edit.
- **2026-10-15** · Paragraph Style Options summarizes captured and pending color, size and
paragraph settings relative to the Based On style.
- **2026-10-15** · Typography uses named panel groups with the Control panel and restores that
arrangement on Reset Workspace, leaving the page clear until a panel is opened.
- **2026-10-13** · Switching between document and parent pages refreshes the canvas immediately, preventing black parent pages and stale document objects when the zoom stays the same. Ordinary edits retain partial repainting. No readiness percentage change.
+43 -5
View File
@@ -918,6 +918,17 @@ pub const CLASSIC_GROUPS: &[&[&str]] = &[
&["gradient"],
];
/// The Typography preset's available panels in the order observed in InDesign's workspace.
/// CC Libraries and the separate Story panel have no corresponding DesignCraft panel.
pub const TYPOGRAPHY_GROUPS: &[&[&str]] = &[
&["pages", "layers", "swatches"],
&["glyphs", "textWrap"],
&["stroke", "gradient"],
&["hyperlinks", "effects"],
&["paragraph", "paragraphStyles"],
&["character", "characterStyles"],
];
pub fn ui_label(id: &str) -> Option<(&'static str, Option<&'static str>)> {
UI_COMMANDS.iter().find(|c| c.0 == id).map(|c| (c.1, c.2))
}
@@ -1858,11 +1869,14 @@ fn run_ui_inner(app: &mut DesignApp, id: &str, p: &Value) -> Option<Result<Value
app.ui.control_bar = matches!(name, "Advanced" | "Typography" | "Printing and Proofing" | "Book" | "Essentials Classic");
// Essentials Classic: the Control panel and an icon column of grouped panels, no
// Properties stack.
let classic = name == "Essentials Classic";
app.ui.icon_groups = classic.then(|| CLASSIC_GROUPS.iter().map(|g| g.iter().map(|p| p.to_string()).collect()).collect());
app.ui.dock_expanded = !classic;
let groups = match name {
"Essentials Classic" => Some(CLASSIC_GROUPS),
"Typography" => Some(TYPOGRAPHY_GROUPS),
_ => None,
};
app.ui.icon_groups = groups.map(|groups| groups.iter().map(|g| g.iter().map(|p| p.to_string()).collect()).collect());
app.ui.dock_expanded = groups.is_none();
let dock_tab = match name {
"Typography" => Some("properties"),
"Interactive for PDF" | "Digital Publishing" => Some("pages"),
_ => None,
};
@@ -1871,7 +1885,6 @@ fn run_ui_inner(app: &mut DesignApp, id: &str, p: &Value) -> Option<Result<Value
app.ui.dock_expanded = true;
}
app.ui.open_panel = match name {
"Typography" => Some("paragraphStyles".into()),
"Printing and Proofing" => Some("swatches".into()),
"Interactive for PDF" => Some("buttons".into()),
"Digital Publishing" => Some("liquid".into()),
@@ -4856,6 +4869,31 @@ mod tests {
assert_eq!(app.ui.icon_groups, Some(groups));
}
#[test]
fn typography_workspace_opens_its_panels_from_named_icon_groups_and_resets() {
let mut app = crate::DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());
run_ui(&mut app, "window.workspace", &json!({"name":"Typography"})).unwrap().unwrap();
assert!(app.ui.control_bar);
assert!(!app.ui.dock_expanded);
assert!(app.ui.open_panel.is_none());
let groups = app.ui.icon_groups.clone().unwrap();
assert_eq!(groups[0], ["pages", "layers", "swatches"]);
assert_eq!(groups[4], ["paragraph", "paragraphStyles"]);
assert_eq!(groups[5], ["character", "characterStyles"]);
for panel in ["pages", "paragraphStyles", "characterStyles"] {
run_ui(&mut app, "window.panel", &json!({"panel":panel})).unwrap().unwrap();
assert_eq!(app.ui.open_panel.as_deref(), Some(panel));
assert!(!app.ui.dock_expanded);
}
run_ui(&mut app, "window.resetWorkspace", &json!({})).unwrap().unwrap();
assert_eq!(app.ui.icon_groups, Some(groups));
assert!(app.ui.open_panel.is_none());
assert!(!app.ui.dock_expanded);
run_ui(&mut app, "window.workspace", &json!({"name":"Essentials"})).unwrap().unwrap();
assert!(app.ui.icon_groups.is_none());
assert!(app.ui.dock_expanded);
}
#[test]
fn the_window_menu_is_in_indesigns_order_and_reaches_every_panel() {
let window = menu_tree().into_iter().find(|(m, _)| *m == "Window").unwrap().1;
+6
View File
@@ -108,6 +108,12 @@ Paragraph Style Options' General pane shows a Style Settings summary of differen
parent, including captured color, size and spacing. Pending edits appear before OK without
changing the document. Fully captured default attributes do not overwhelm the summary. This
covers checking the sampled and redefined settings in the styles tutorial (2:45 and 5:15).
Typography now starts and resets with the Control panel and named panel groups along the right
edge, including Paragraph/Paragraph Styles and Character/Character Styles. It does not open
Properties or a Styles flyout over the new page. This matches the available panels at 0:05–0:15
in [Jessica Garrity's styles tutorial](https://www.youtube.com/watch?v=pG9JkAPLgs8).
CC Libraries and a separate Story panel are absent; these are not needed for the tutorial's
style operations. The flyout tabs and detailed controls remain separate UI parity work.
| Work | Opus 5.5 h |
|---|---|