diff --git a/crates/ui-egui/src/dialogs.rs b/crates/ui-egui/src/dialogs.rs index 158b9d07d..6335f8fca 100644 --- a/crates/ui-egui/src/dialogs.rs +++ b/crates/ui-egui/src/dialogs.rs @@ -1005,13 +1005,14 @@ fn selected_frame_options(app: &DesignApp) -> Option bool { - let shaped = || { - let st = app.session.active()?; - let fid = st.selection.items.first().copied().or_else(|| st.selection.text.and_then(|t| t.frame))?; + let Some(st) = app.session.active() else { return false }; + let shaped = |fid: designcraft_doc::ItemId| -> Option { let item = st.doc.item(fid)?; if item.text_frame()?.options.path.is_some() { return Some(false); @@ -1019,7 +1020,11 @@ fn selected_frame_is_shaped(app: &DesignApp) -> bool { let bp = if item.corners.is_none() { item.path.to_bezpath() } else { designcraft_geom::corners::apply(&item.path, &item.corners) }; Some(designcraft_compose::FrameOutline::new(&bp, 0.0).is_some()) }; - shaped().unwrap_or(false) + if st.selection.items.is_empty() { + let Some(fid) = st.selection.text.and_then(|t| t.frame) else { return false }; + return shaped(fid).unwrap_or(false); + } + st.selection.items.iter().all(|&fid| shaped(fid).unwrap_or(false)) } /// Object › Text Frame Options shows the selected frame's options. `_shown` keeps what it showed, diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 4207507dc..f950eb12c 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -352,7 +352,7 @@ It is evidence of breadth: each item exists. It is not a claim of InDesign-level - Auto-size (Text Frame Options › Auto-Size, `object.textFrameOptions {autoSize: off|heightOnly|widthOnly|heightAndWidth|heightAndWidthProportionally, autoSizeReference, useMinimumHeight, minimumHeight, useMinimumWidth, minimumWidth, noLineBreaks}`): the frame fits its text exactly after every edit (typing, pasting, style changes, option changes) in the same undo step (opening a file keeps the frame sizes it gives); it grows and shrinks around the reference point, which stays put in spread space for rotated frames too, never below the minimum height/width and never past 10,000 pt. Width Only and No Line Breaks set each paragraph on one line; Height and Width without No Line Breaks keeps the width; Keep Proportions scales both sides until the text fits. IDML keeps all the options (`AutoSizing…`, `…ForAutoSizing` attributes). Not covered: frames of a thread other than the last, vertical frames, type on a path, and multi-column balancing in Keep Proportions. - Balance Columns (Text Frame Options › Balance Columns, `object.textFrameOptions {balanceColumns}`, IDML `VerticalBalanceColumns`): in the frame the story ends in, the columns after the last explicit column break fill to about the same depth (the last may be shorter by a line per column); keep options hold, spanning and split paragraphs keep their own balancing, vertical justification then applies to each column as usual, and vertical frames balance their bands. A frame the text runs on from, or that is overset, fills normally. - Text Frame Options dialog, laid out as InDesign's (General, Column Rules, Baseline Options, Auto-Size; framed Columns, Inset Spacing and Vertical Justification groups with spinner fields; Fixed Number shows each column's width as the fields change). Preview shows the edits on the page until OK (one undo step) or Cancel. An invalid value (such as a gutter that isn't a measure) takes the preview off the page, so the frame shows as it was, and the dialog's status line gives the reason; OK refuses the value too. Preview stays checked and shows the edits again once the value is valid. Vertical Justification › Paragraph Spacing Limit (`object.textFrameOptions {paragraphSpacingLimit}`, IDML `VerticalThreshold`): with Justify, the extra space goes between paragraphs up to the limit, the rest between lines. -- Text Frame Options › Inset Spacing for a non-rectangular frame (an oval, a polygon, a frame with corner options): Top, Left, Bottom, Right and the link are dimmed, and one Inset field sets the distance kept between the text and the frame's outline (`object.textFrameOptions {inset: }`, all four sides). +- Text Frame Options › Inset Spacing for a non-rectangular frame (an oval, a polygon, a frame with corner options; when every selected text frame is one, a mixed selection keeps the four sides): Top, Left, Bottom, Right and the link are dimmed, and one Inset field sets the distance kept between the text and the frame's outline (`object.textFrameOptions {inset: }`, all four sides). - Place a page of an IDML or DesignCraft document (`file.place {layoutPage}`): its objects, stories, styles and swatches as one group (INDD files are not readable). - Articles panel (`article.new/add/remove/options/delete/list`): reading order and content of EPUB and HTML exports. - Object ▸ Clipping Path (`object.clippingPath {type: alpha|edges, threshold, tolerance}`): traces the placed image and makes the outline the frame. Clipping paths saved in IDML (Detect Edges, Alpha Channel, Photoshop Path, User-Modified Path; Invert) hide the image outside the path on screen and in PDF and survive IDML export; `object.clippingPathOptions` reports, inverts or removes one (Object ▸ Clipping Path ▸ None).