mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Type tool: Escape returns to the previous selection tool and preserves isolation mode
When entering text edit mode via double-click from a selection tool (Selection or Direct Selection), pressing Escape now returns to the specific tool used before double-clicking (rather than always falling back to Selection). Additionally, when editing text while in isolation mode (such as when drilling into nested groups with the Selection tool), pressing Escape exits text editing while keeping isolation mode active; a second Escape press is required to exit isolation mode. - Record the previous tool in TypeTool on double-click from canvas. - Return to prev_tool on ToolKey::Escape, consuming the key in shortcuts when claimed. - Add unit test in vectorcraft-tools verifying Escape returns to prev_tool. - Add integration tests in vectorcraft-ui-egui verifying Escape returns to Direct Selection and that isolation mode persists until a second Escape. - Update docs/target-app-parity.md and ROADMAP.md.
This commit is contained in:
+1
-1
@@ -132,7 +132,7 @@ Ranked; detail in [docs/roadmap.md](docs/roadmap.md) and [docs/gaps.md](docs/gap
|
||||
|
||||
| Date | What landed |
|
||||
|---|---|
|
||||
| 2026-10-14 | Corner Radius has a link button in Properties and Transform: unlinked, a live rectangle shows a radius field for each corner (#1682). With the Width tool, double-clicking a stroke opens Width Point Edit to create a width point there, and Shift-double-click on a width point opens it with Adjust Adjoining Width Points ticked (#1814, #1630). Holding Alt while dragging a guide out of a ruler switches it between horizontal and vertical (#1782), and a marquee with the Selection or Direct Selection tool also selects the unlocked ruler guides it crosses (#1836). The Transform panel's, Properties panel's and Control bar's X/Y/W/H show and edit only the anchor points selected with Direct Selection (#1839, fixes #1824). With the Direct Selection tool, double-clicking type (including type nested inside a group) switches to the Type tool and puts the caret at the clicked character. With Snap to Grid on, anchors and objects snap to the grid even when Snap to Pixel is also ticked (#1840; #1816 waits for the reporter). Artboards are deleted the same way from the Artboards panel, its menu, Properties and Delete/Backspace (#1631). The toolbar shows no group labels by default (a preference brings them back) and runs on in one or two columns; the All Tools drawer lists the tools by flyout group with their shortcuts, has a menu (Reset, Basic, Advanced) and a Show section for the Fill/Stroke, Coloring, Draw Mode and Screen Mode controls (#1751). An action clicked in the Actions panel stays selected, so Play Current Selection and Delete Selection act on it (#1853, part of #1629). Redo during a drag keeps the drag as a step (#1856, #1719). Preferences are written as soon as OK is pressed (#1857; #1747 waits for the reporter). Preferences › Appearance of Black › Printing / Exporting and Units › Identify Objects By act (#1750, #1809). The paragraph alignment buttons show none selected for paragraphs with different alignments (#1784); redefining a character style to Auto leading updates the text that uses it and keeps local overrides (#1633); New and Redefine Character Style take the format of the selected text range, also while typing (#1634). Type inside symbols, pattern tiles, graph designs and opacity masks gets its layout bounds back when a native file opens, so warped type in a symbol looks the same after save and reopen (#1833, #1738). Editing, renaming, deleting or merging a global swatch reaches the art of opacity masks (#1830, #1735). macOS: Save As, Save a Copy and the first Save show their sheet again; the sheet's Format menu (#866, reopened) is withdrawn until it can be set before the sheet opens (#1855). |
|
||||
| 2026-10-14 | Corner Radius has a link button in Properties and Transform: unlinked, a live rectangle shows a radius field for each corner (#1682). With the Width tool, double-clicking a stroke opens Width Point Edit to create a width point there, and Shift-double-click on a width point opens it with Adjust Adjoining Width Points ticked (#1814, #1630). Holding Alt while dragging a guide out of a ruler switches it between horizontal and vertical (#1782), and a marquee with the Selection or Direct Selection tool also selects the unlocked ruler guides it crosses (#1836). The Transform panel's, Properties panel's and Control bar's X/Y/W/H show and edit only the anchor points selected with Direct Selection (#1839, fixes #1824). With the Direct Selection tool, double-clicking type (including type nested inside a group) switches to the Type tool and puts the caret at the clicked character; pressing Escape finishes editing and returns to the selection tool used before double-clicking, and in isolation mode the first Escape exits editing while preserving isolation until a second Escape. With Snap to Grid on, anchors and objects snap to the grid even when Snap to Pixel is also ticked (#1840; #1816 waits for the reporter). Artboards are deleted the same way from the Artboards panel, its menu, Properties and Delete/Backspace (#1631). The toolbar shows no group labels by default (a preference brings them back) and runs on in one or two columns; the All Tools drawer lists the tools by flyout group with their shortcuts, has a menu (Reset, Basic, Advanced) and a Show section for the Fill/Stroke, Coloring, Draw Mode and Screen Mode controls (#1751). An action clicked in the Actions panel stays selected, so Play Current Selection and Delete Selection act on it (#1853, part of #1629). Redo during a drag keeps the drag as a step (#1856, #1719). Preferences are written as soon as OK is pressed (#1857; #1747 waits for the reporter). Preferences › Appearance of Black › Printing / Exporting and Units › Identify Objects By act (#1750, #1809). The paragraph alignment buttons show none selected for paragraphs with different alignments (#1784); redefining a character style to Auto leading updates the text that uses it and keeps local overrides (#1633); New and Redefine Character Style take the format of the selected text range, also while typing (#1634). Type inside symbols, pattern tiles, graph designs and opacity masks gets its layout bounds back when a native file opens, so warped type in a symbol looks the same after save and reopen (#1833, #1738). Editing, renaming, deleting or merging a global swatch reaches the art of opacity masks (#1830, #1735). macOS: Save As, Save a Copy and the first Save show their sheet again; the sheet's Format menu (#866, reopened) is withdrawn until it can be set before the sheet opens (#1855). |
|
||||
| 2026-10-14 | Rendering: copies, symbol instances and repeats that share an appearance keep their stroke outlines between frames (#1667); the canvas no longer reads its whole picture back for each non-isolated group that blends (#1687); envelopes, blends, repeats and meshes redraw when a pattern, symbol, font or colour setting they show changes (#1688); Outline view draws from geometry kept between frames (#1689); CMYK documents with transparency compose their ink planes on several threads (#1755); an edit re-flows a threaded story only when it changes one of the story's frames (#1792); opening a file reads its linked files and lays out its type on the opening thread (#1767). Instances of imported symbols are measured, selected, aligned, culled and exported by their art instead of a 20 pt square (#1744). Export for Screens and the Asset Export panel offer TIFF (#1632). SVG import looks style rules up by id, class and type (#1690), applies `:not()` selectors (#1799, #1557), no longer stalls on stacked descendant selectors over deep nesting (#1834, #1703) and reads linked files within the automation roots again (#1870). DXF export writes the VPORT view direction once (#1789). Untrusted files: nesting is capped at 32 objects in SVG, PDF, EPS and native files and symbols or patterns that use themselves open without the offending instance or paint (#1852); deeply nested PDF and `.ai` data, page trees holding themselves and functions or colour spaces built on themselves (#1871), decompression bombs and impossible predictor parameters (#1873, #1700, #1701), brushes that draw themselves (#1872) and hostile EPS, Affinity and native data (#1863: #1715, #1714, #1704, #1699) no longer crash or exhaust the app; the save fallback keeps the old file until the new one is in (#1695). Files whose ids sit at their largest value, a failed `command.batch`, control requests that timed out and images too large as RGBA for the Eyedropper are handled (#1862: #1718, #1697, #1725, #1717). Effects: wide shadows and glows at high zoom stay within the raster budget, stacked Transform effects are bounded, 3D keeps the area a nonzero compound path fills, pattern tiles redraw when the art they show changes, and a template layer dims its images by Dim Images (#1864: #1706, #1705, #1724, #1723, #1683). A failed save or export is reported in a dialog that names the file and stays until closed (#1865, #1685); a browser download that can't start fails the save (#1693); a file that finishes opening waits while a dialog is open (#1694). krilla's text shaping is no longer built in (#1874, #1730); the CI gate compiles the web app for wasm (#1875). |
|
||||
| 2026-10-14 | Image Trace: Shapes finds rounded rectangles and shapes in blurred and scanned art (98 to 100% of the plain-shape inputs, from 57 to 62%; #1845), square-ended lines get square caps (Outline's largest distance 2.94 px to 0.88; #1846), each documented preset has an enhanced version with Auto Grouping and Shapes that measures no worse than the preset (#1847), and blurred or noisy linear gradients trace as one gradient-filled path instead of 3 to 56 (#1848) ([`docs/image-trace-quality.md`](docs/image-trace-quality.md)). No headline number moves. |
|
||||
| 2026-10-13 | Synthetic control input has finite click/drag counts and pending-event limits, checked before queue mutation; control-channel bursts yield after 64 requests per frame (#1709). |
|
||||
|
||||
@@ -66,6 +66,8 @@ type CachedLayout = ((u64, TextObject), Arc<TextLayout>);
|
||||
pub struct TypeTool {
|
||||
vertical: bool,
|
||||
mode: Mode,
|
||||
/// The tool to return to on Escape (e.g. when double-clicked from a selection tool).
|
||||
prev_tool: Option<String>,
|
||||
/// Text object being edited.
|
||||
editing: Option<NodeId>,
|
||||
/// The point type a click just placed (edited now): discarded if empty when editing ends.
|
||||
@@ -526,11 +528,13 @@ impl Tool for TypeTool {
|
||||
self.goal_x = None;
|
||||
}
|
||||
match key {
|
||||
// Escape ends editing and goes to the Selection tool, the type selected: the keyboard
|
||||
// is free for tool shortcuts again (#1686).
|
||||
// Escape ends editing and goes back to the tool used before double-clicking into type
|
||||
// (or to the Selection tool by default), the type selected: the keyboard is free for
|
||||
// tool shortcuts again (#1686).
|
||||
ToolKey::Escape => {
|
||||
let target = self.prev_tool.take().unwrap_or_else(|| "selection".into());
|
||||
let mut out = self.finish(cx);
|
||||
out.push(Action::SwitchTool("selection".into()));
|
||||
out.push(Action::SwitchTool(target));
|
||||
out
|
||||
}
|
||||
ToolKey::Enter => self.replace(cx, "\n", None),
|
||||
@@ -664,6 +668,7 @@ impl Tool for TypeTool {
|
||||
Some((t.xf * a, t.xf * b))
|
||||
}
|
||||
fn deactivate(&mut self, cx: &ToolContext) -> Vec<Action> {
|
||||
self.prev_tool = None;
|
||||
self.finish(cx)
|
||||
}
|
||||
/// Editing ends when a command takes the text out of the selection (Deselect, another object
|
||||
@@ -698,15 +703,27 @@ impl Tool for TypeTool {
|
||||
Some(id) => {
|
||||
// Offsets may exceed the text after Select All; callers clamp to the text length.
|
||||
let (a, b) = self.sel();
|
||||
json!({"editing": id.0, "start": a, "end": b, "caret": self.caret, "anchor": self.anchor, "typing": self.typing.is_some(), "composing": self.preedit.is_some()})
|
||||
json!({
|
||||
"editing": id.0,
|
||||
"start": a,
|
||||
"end": b,
|
||||
"caret": self.caret,
|
||||
"anchor": self.anchor,
|
||||
"typing": self.typing.is_some(),
|
||||
"composing": self.preedit.is_some(),
|
||||
"prevTool": self.prev_tool,
|
||||
})
|
||||
}
|
||||
None => json!({"editing": null}),
|
||||
None => json!({"editing": null, "prevTool": self.prev_tool}),
|
||||
}
|
||||
}
|
||||
/// `select {start, end}` / `selectAll` / `copy` (with `runs` of the selection) /
|
||||
/// `commitTyping` (the caller commits the engine interaction).
|
||||
fn set_option(&mut self, key: &str, v: &Value) {
|
||||
match key {
|
||||
"prevTool" | "previousTool" => {
|
||||
self.prev_tool = v.as_str().map(String::from);
|
||||
}
|
||||
"commitTyping" | "endTyping" => {
|
||||
self.typing = None;
|
||||
self.preedit = None;
|
||||
@@ -731,6 +748,7 @@ impl Tool for TypeTool {
|
||||
self.typing = None;
|
||||
self.preedit = None;
|
||||
self.editing = None;
|
||||
self.prev_tool = None;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -387,3 +387,16 @@ fn layout_cache_follows_fonts_added_later() {
|
||||
assert!(FontDb::global().add_font(font) > 0, "the test font is new to this process");
|
||||
assert!(!Arc::ptr_eq(&before, &tool.layout(t)), "a font added after the layout must refresh it");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escape_returns_to_previous_tool_when_set() {
|
||||
let (d, _id, mut tool) = editing("Hello");
|
||||
tool.set_option("prevTool", &json!("directSelection"));
|
||||
let acts = key(&mut tool, &d, ToolKey::Escape, Mods::default());
|
||||
assert_eq!(acts.last(), Some(&Action::SwitchTool("directSelection".into())));
|
||||
|
||||
// Without prevTool set, Escape defaults to Selection tool.
|
||||
let (d2, _id2, mut tool2) = editing("World");
|
||||
let acts2 = key(&mut tool2, &d2, ToolKey::Escape, Mods::default());
|
||||
assert_eq!(acts2.last(), Some(&Action::SwitchTool("selection".into())));
|
||||
}
|
||||
|
||||
@@ -816,6 +816,7 @@ fn handle_input(app: &mut VectorcraftApp, ui: &Ui, resp: &egui::Response, rect:
|
||||
// A double-click on type switched a selection tool to the Type tool: the caret goes where
|
||||
// the type was clicked, so typing edits it at once.
|
||||
if before != "type" && app.session.tool_id() == "type" {
|
||||
app.session.set_tool_option("prevTool", &json!(before));
|
||||
for kind in [PointerKind::Down, PointerKind::Up] {
|
||||
dispatch(app, &PointerEvent { kind, ..ev }, view);
|
||||
}
|
||||
@@ -4351,8 +4352,10 @@ mod tests {
|
||||
let ctx = egui::Context::default();
|
||||
let timed = |app: &mut VectorcraftApp, time: f64, events: Vec<egui::Event>| {
|
||||
let screen = egui::Rect::from_min_size(Pos2::ZERO, vec2(800.0, 600.0));
|
||||
let mut out =
|
||||
ctx.run_ui(egui::RawInput { screen_rect: Some(screen), time: Some(time), events, ..Default::default() }, |ui| show(app, ui));
|
||||
let mut out = ctx.run_ui(egui::RawInput { screen_rect: Some(screen), time: Some(time), events, ..Default::default() }, |ui| {
|
||||
crate::shortcuts::handle(app, ui.ctx());
|
||||
show(app, ui)
|
||||
});
|
||||
out.textures_delta.clear();
|
||||
};
|
||||
timed(&mut app, 0.0, vec![]);
|
||||
@@ -4378,6 +4381,65 @@ mod tests {
|
||||
app.session.tool_text("X", app.view_info()).unwrap();
|
||||
let t = text(&app);
|
||||
assert_eq!((t.len(), t.find('X')), (12, Some(caret as usize)), "{t}");
|
||||
|
||||
// Pressing Escape exits text editing and returns to Direct Selection tool.
|
||||
let esc = |pressed| egui::Event::Key { key: egui::Key::Escape, physical_key: None, pressed, repeat: false, modifiers: Default::default() };
|
||||
timed(&mut app, 1.2, vec![esc(true), esc(false)]);
|
||||
assert_eq!(app.session.tool_id(), "directSelection");
|
||||
assert!(!app.session.tool_wants_text());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escape_while_editing_in_isolation_returns_to_selection_tool_and_keeps_isolation_until_second_escape() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
|
||||
let tid =
|
||||
app.session.execute("text.create", &json!({"x": 100, "y": 150, "text": "Nested hello", "size": 24})).unwrap()["id"].as_u64().unwrap();
|
||||
// Group the text inside a group.
|
||||
app.session.execute("select.all", &json!({})).unwrap();
|
||||
app.session.execute("object.group", &json!({})).unwrap();
|
||||
app.select_tool("selection");
|
||||
let ctx = egui::Context::default();
|
||||
let timed = |app: &mut VectorcraftApp, time: f64, events: Vec<egui::Event>| {
|
||||
let screen = egui::Rect::from_min_size(Pos2::ZERO, vec2(800.0, 600.0));
|
||||
let mut out = ctx.run_ui(egui::RawInput { screen_rect: Some(screen), time: Some(time), events, ..Default::default() }, |ui| {
|
||||
crate::shortcuts::handle(app, ui.ctx());
|
||||
show(app, ui)
|
||||
});
|
||||
out.textures_delta.clear();
|
||||
};
|
||||
timed(&mut app, 0.0, vec![]);
|
||||
let xf = Xf::new(app.canvas_rect.unwrap(), app.view().unwrap());
|
||||
let b = app.session.active().unwrap().doc.node(vectorcraft_doc::NodeId(tid)).unwrap().geometric_bounds().unwrap();
|
||||
let at = xf.to_screen(b.center());
|
||||
let button = |pressed| egui::Event::PointerButton { pos: at, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() };
|
||||
let esc = |pressed| egui::Event::Key { key: egui::Key::Escape, physical_key: None, pressed, repeat: false, modifiers: Default::default() };
|
||||
|
||||
// 1st double-click on group enters isolation mode.
|
||||
timed(&mut app, 1.0, vec![egui::Event::PointerMoved(at), button(true), button(false), button(true), button(false)]);
|
||||
timed(&mut app, 1.1, vec![]);
|
||||
assert!(app.session.active().unwrap().isolation.is_some(), "should be in isolation mode");
|
||||
assert_eq!(app.session.tool_id(), "selection");
|
||||
|
||||
// 2nd double-click on the text inside the isolated group enters text editing.
|
||||
timed(&mut app, 2.0, vec![egui::Event::PointerMoved(at), button(true), button(false), button(true), button(false)]);
|
||||
timed(&mut app, 2.1, vec![]);
|
||||
assert_eq!(app.session.tool_id(), "type");
|
||||
assert!(app.session.tool_wants_text());
|
||||
assert!(app.session.active().unwrap().isolation.is_some(), "isolation mode still active while editing text");
|
||||
|
||||
// 1st Escape exits text edit mode, returns to Selection tool, but keeps isolation mode.
|
||||
timed(&mut app, 3.0, vec![esc(true), esc(false)]);
|
||||
timed(&mut app, 3.1, vec![]);
|
||||
assert_eq!(app.session.tool_id(), "selection");
|
||||
assert!(!app.session.tool_wants_text());
|
||||
assert!(app.session.active().unwrap().isolation.is_some(), "1st Escape must NOT end isolation mode");
|
||||
|
||||
// 2nd Escape exits isolation mode.
|
||||
timed(&mut app, 4.0, vec![esc(true), esc(false)]);
|
||||
timed(&mut app, 4.1, vec![]);
|
||||
assert_eq!(app.session.tool_id(), "selection");
|
||||
assert!(app.session.active().unwrap().isolation.is_none(), "2nd Escape must exit isolation mode");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -261,6 +261,9 @@ pub fn handle(app: &mut VectorcraftApp, ctx: &egui::Context) {
|
||||
if claimed || (k == Key::Enter && !busy) {
|
||||
crate::canvas::apply_requests(app, r);
|
||||
}
|
||||
if claimed {
|
||||
ctx.input_mut(|i| i.consume_key(Modifiers::NONE, k));
|
||||
}
|
||||
if k == Key::Escape && !busy && !claimed {
|
||||
// Escape leaves Presentation Mode first: it hides the menus and panels.
|
||||
if app.ui.screen_mode == 3 {
|
||||
|
||||
@@ -474,6 +474,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- **Path editing (#494):** the handles shown are the handles that drag: Direct Selection drags those of a path selected as a whole (as the Pen leaves it), the Anchor Point tool and Pen+Alt no longer grab handles that Show handles when multiple anchors are selected hides, a handle shorter than the tolerance leaves its anchor to be picked, and the anchor tools pick within Selection & Anchor Display › Tolerance. A dragged segment keeps a smooth anchor at either end smooth. With Direct Selection, the Pen, the Curvature and the anchor tools, a path selected as a whole shows all its anchors selected, and the Control bar and the Properties panel offer Convert (corner, smooth) for them too; Remove and Cut wait for anchors direct-selected (#504). A handle drag gathers its snap targets once per drag (it took 21 ms per pointer move on a 20,000-path document, now 1 ms; `vectorcraft-cli perf` measures handle and segment drags on a 5,000-anchor path). Join merges the selected anchor points that lie on one another, as after Average, into one anchor (#1582, fixes #1533); Average and Join in one step, with a corner or smooth choice for the joined anchor, is missing ([gap 1](gaps.md)).
|
||||
- **Graphs:** Column, Stacked Column, Bar, Stacked Bar, Line, Area, Scatter, Pie and Radar graph tools with Graph Data and Graph Type. A series starts in greyscale; Group Selection's fill and stroke are kept separately on the graph and reapplied when its data, type or size changes, and through save, open and undo. Graph Type's Override Calculated Values (both `axisMin` and `axisMax`) uses exactly that value-axis range, split into the tick count (5 when automatic). Line graphs take Edge-to-Edge Lines (off by default: the points sit at the centres of their categories; graphs saved before the option keep their edge-to-edge lines), and radar graphs follow Mark Data Points and Connect Data Points. Blank cells (an empty CSV cell or `null`) are values left out, not zeros: columns, bars and stacked segments skip them, lines and scatter lines break around them and the value axis ignores them, while area, pie and radar draw them as 0; a number in straight quotes is a label, and the data window writes it back quoted. Graph types combine: Graph Type on series picked with Group Selection (or `series` indexes) draws them as their own type, with column, stacked column, line and area mixing on the vertical value axis and bar and stacked bar on the horizontal one; stacked columns take one slot of the cluster, lines draw in front of columns and areas behind. The value axis goes on the left, the right or both sides (column, stacked column, line, area and scatter graphs; bar graphs keep theirs along the bottom), and Separate Scales gives the series assigned to the right axis a scale of their own with its own tick values. Each value axis takes tick marks of no, short or full (across the plot) length and a count per division, and a prefix and suffix for its numbers; the category axis takes tick marks too (none by default), at or between its labels. Graph designs: Object › Graph › Design lists the designs with a preview of the selected one, and New Design (the selected art), Rename, Delete Design, Paste Design (a copy back to edit) and Select Unused, and Marker draws the data points and legend swatches of line, scatter and radar series with a design, scaled so its backmost object fills the default marker's square. Graph Data transposes rows and columns and switches a scatter graph's x and y, and a `|` in a category or series label starts a new line. Pie graphs take Legends in Wedges, Position (Even, Ratio sized by area, Stacked on one centre) and Sort (None, All, First). Graph Type takes column and cluster widths up to 1000% (overlapping past 100%) with First Row and First Column in Front (First Row orders each series' categories; across series the series order decides, so series stay one group each for Group Selection), draws filled lines, adds drop shadows behind columns, bars, lines and wedges, and puts the legend in rows across the top. Text formatted with the Character or Appearance controls, on the whole graph or on labels picked with Group Selection, is kept per kind of label (value axis numbers, category labels, legend labels) through the graph being drawn again. Object › Graph › Data opens a worksheet: cells picked with a click and edited above the sheet (Tab moves right, Enter down, the arrows between cells), Import Data from a tab-separated text file, Transpose, Switch x/y, Cell Style (decimals shown, column width), Revert and Apply. Column designs remain open. `graph.setData` returns and takes the data as CSV with each value written exactly, not rounded to two decimals, so applying the returned CSV changes nothing (#1485).
|
||||
- **Other:** Eyedropper, Gradient annotator, Artboard (Alt-drag duplicates an artboard, and its art with Move/Copy Artwork with Artboard on; Copy, Cut and Paste take the artboard with its art, Paste right of the last artboard, Paste in Place where it was, into this or another document, #446; Object › Artboards › Rearrange All Artboards lays them out in a grid by row or by column, in one row or one column, left to right or right to left, from the menu, the Artboards panel or Properties' Rearrange All, #681; Scale Artwork with Artboard, in the Control bar and Properties beside Move Artwork with Artboard, resizes the artboard proportionally with the art fully inside it and its guides, strokes and corners per the Scale preferences, #602), Measure, Type, Hand, Zoom, Rotate View.
|
||||
- **Editing type:** double-clicking type with a selection tool (Selection or Direct Selection) switches to the Type tool with the caret where it was clicked; pressing Escape finishes editing and switches back to the selection tool used before double-clicking it (when in isolation mode, the first Escape exits text editing while preserving isolation mode, and a second Escape exits isolation).
|
||||
- **Editing type:** double-clicking type with a selection tool (Selection or Direct Selection) switches to the Type tool with the caret where it was clicked.
|
||||
Duplicate Artboards, the Artboard tool's Alt-drag and Paste give the new artboard an id that no other artboard has, also when an artboard's id is the largest possible value (#1718). Deleting the copy or the original then leaves the other's guides.
|
||||
- **Editing type:** double-clicking type with a selection tool switches to the Type tool with the caret where it was clicked.
|
||||
|
||||
Reference in New Issue
Block a user