mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Merge pull request #1947 from marcoarnulfo/fix/text-center-shortcut-and-autosize
Text: Ctrl+Shift+C aligns centre off the Mac, a double-click on area type's bottom handle turns on Auto Size
This commit is contained in:
@@ -130,6 +130,26 @@ pub(crate) fn paste_command(held: Modifiers) -> &'static str {
|
||||
.map_or("edit.paste", |(_, id, _)| id)
|
||||
}
|
||||
|
||||
/// Give a copy or cut chord held with more modifiers its key back when it has a shortcut of its own:
|
||||
/// egui reports every Cmd+C and Cmd+X chord as Copy or Cut, Shift and Alt held too, so Cmd+Shift+C
|
||||
/// (Align center) copied instead (#1940).
|
||||
fn unclip_chords(i: &mut egui::InputState) {
|
||||
if !i.events.iter().any(|e| matches!(e, egui::Event::Copy | egui::Event::Cut)) {
|
||||
return;
|
||||
}
|
||||
let (held, shortcuts) = (i.modifiers, all_shortcuts());
|
||||
for e in &mut i.events {
|
||||
let (key, own) = match e {
|
||||
egui::Event::Copy => (Key::C, "edit.copy"),
|
||||
egui::Event::Cut => (Key::X, "edit.cut"),
|
||||
_ => continue,
|
||||
};
|
||||
if shortcuts.iter().any(|(sc, id, _)| sc.logical_key == key && *id != own && held.matches_exact(sc.modifiers)) {
|
||||
*e = egui::Event::Key { key, physical_key: None, pressed: true, repeat: false, modifiers: held };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Keyboard pastes of something other than text. egui swallows a paste chord's key press and
|
||||
/// sends a Paste event only when the clipboard holds text, so a paste key released without its
|
||||
/// press (or a Paste event) reported was a paste of a bitmap or a PDF.
|
||||
@@ -294,6 +314,7 @@ pub fn handle(app: &mut VectorcraftApp, ctx: &egui::Context) {
|
||||
if typing {
|
||||
return;
|
||||
}
|
||||
ctx.input_mut(unclip_chords);
|
||||
// Tab is ours when no field has the keyboard (it shows and hides the panels, or goes to the
|
||||
// Type tool): left to egui, it would also move the focus on to a field, and every key after it
|
||||
// would count as typing.
|
||||
|
||||
@@ -73,3 +73,38 @@ fn a_paste_takes_the_command_of_the_v_chord_held() {
|
||||
fn no_two_commands_tools_or_panels_share_a_default_shortcut() {
|
||||
assert_eq!(shortcut_editor::all_conflicts(&BTreeMap::new()), vec![]);
|
||||
}
|
||||
|
||||
/// egui-winit reports every Cmd+C chord as a Copy, Shift and Alt held too, never as its key: the
|
||||
/// Cmd+Shift+C alignment fired on a Mac (the menu's key equivalent) but copied elsewhere (#1940).
|
||||
#[test]
|
||||
fn a_copy_with_more_modifiers_is_the_c_chord_held() {
|
||||
use vectorcraft_doc::{Justify, NodeId, NodeKind};
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width": 200, "height": 200})).unwrap();
|
||||
let id = app.run("text.create", json!({"x": 20, "y": 50, "text": "One\nTwo"})).unwrap()["id"].as_u64().unwrap();
|
||||
let justify = |app: &VectorcraftApp| match &app.session.active().unwrap().doc.node(NodeId(id)).unwrap().kind {
|
||||
NodeKind::Text(t) => (0..t.paragraph_count()).map(|i| t.para_at(i).justify).collect::<Vec<_>>(),
|
||||
_ => panic!("text"),
|
||||
};
|
||||
let copied = |out: &egui::FullOutput| out.platform_output.commands.iter().any(|c| matches!(c, egui::OutputCommand::CopyText(_)));
|
||||
app.run("select.set", json!({"ids": [id]})).unwrap();
|
||||
let out = frame(&mut app, Modifiers::COMMAND | Modifiers::SHIFT, vec![Event::Copy]);
|
||||
assert_eq!(justify(&app), [Justify::Center, Justify::Center]);
|
||||
assert!(!copied(&out), "Cmd+Shift+C doesn't copy");
|
||||
// Cmd+C still copies.
|
||||
let out = frame(&mut app, Modifiers::COMMAND, vec![Event::Copy]);
|
||||
assert!(copied(&out));
|
||||
// While the Type tool edits text, it aligns the paragraph the caret is in.
|
||||
app.select_tool("type");
|
||||
app.session.apply_actions(vec![vectorcraft_tools::Action::Notify("text.editNew".into())]).unwrap();
|
||||
app.session.set_tool_option("select", &json!({"start": 5, "end": 5}));
|
||||
assert!(app.session.tool_wants_text());
|
||||
frame(
|
||||
&mut app,
|
||||
Modifiers::COMMAND | Modifiers::SHIFT,
|
||||
vec![Event::Key { key: Key::R, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::COMMAND | Modifiers::SHIFT }],
|
||||
);
|
||||
assert_eq!(justify(&app), [Justify::Center, Justify::Right]);
|
||||
frame(&mut app, Modifiers::COMMAND | Modifiers::SHIFT, vec![Event::Copy]);
|
||||
assert_eq!(justify(&app), [Justify::Center, Justify::Center]);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
+3
-1
@@ -1,6 +1,6 @@
|
||||
# Type parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** minor (MCP `add_text` exposes the existing `vertical` option for point, area and path type; horizontal remains the default; scores and hours unchanged; Vertical fullwidth question and exclamation marks keep their nominal glyph upright when the font has no vertical alternate; scores and hours unchanged. tab leaders are drawn in the tab's gap, #1877; type in symbols, pattern tiles, graph designs and opacity masks gets its layout bounds back on opening a native file, #1738; score unchanged; Escape while typing ends the edit, #1686; Select › Same on type, #1737; `justify` when creating point type, #1748; scores unchanged; OpenType stylistic sets, alternates, figure styles, superscript and subscript as character features, #1607; a wide word in non-rectangular area type moves down, #1615; scores unchanged; Character Styles New/Redefine capture the first selected character at run boundaries and end prior typing before capture; boundary and typing-history input tests and full workspace CI pass; scores and hours unchanged; Character styles retain explicit Auto leading, propagate resets and preserve local leading overrides; scores and hours unchanged; Linux font folders from fontconfig, #1529; commands and MCP `add_text` report area type that does not fit its frame, #1471; Tabs panel stop drags, #1458; Fit Headline in a frame one line tall, #1444; frames and paths beyond a billion points hold no text, #1451; scores unchanged; missing glyphs are looked for again after a font rescan, #1376; scores unchanged; Full-name font matching (#1258); Windows font-service QA pending; scores unchanged; Middle Eastern digit types: Character panel menu › Digits, `{digits}`; the font menu's script filter lists Thai fonts; Thai, Lao, Khmer and Myanmar lines break between words; the caret steps over whole clusters such as Thai consonants with their marks; Thai typed in a font without Thai falls back to a font made for Thai; earlier: Proportional Metrics in vertical type, `vpal`, #966) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** minor (Cmd+Shift+C aligns centre off the Mac, #1940; tab leaders are drawn in the tab's gap, #1877; type in symbols, pattern tiles, graph designs and opacity masks gets its layout bounds back on opening a native file, #1738; score unchanged; Escape while typing ends the edit, #1686; Select › Same on type, #1737; `justify` when creating point type, #1748; scores unchanged; OpenType stylistic sets, alternates, figure styles, superscript and subscript as character features, #1607; a wide word in non-rectangular area type moves down, #1615; scores unchanged; Character Styles New/Redefine capture the first selected character at run boundaries and end prior typing before capture; boundary and typing-history input tests and full workspace CI pass; scores and hours unchanged; Character styles retain explicit Auto leading, propagate resets and preserve local leading overrides; scores and hours unchanged; Linux font folders from fontconfig, #1529; commands and MCP `add_text` report area type that does not fit its frame, #1471; Tabs panel stop drags, #1458; Fit Headline in a frame one line tall, #1444; frames and paths beyond a billion points hold no text, #1451; scores unchanged; missing glyphs are looked for again after a font rescan, #1376; scores unchanged; Full-name font matching (#1258); Windows font-service QA pending; scores unchanged; Middle Eastern digit types: Character panel menu › Digits, `{digits}`; the font menu's script filter lists Thai fonts; Thai, Lao, Khmer and Myanmar lines break between words; the caret steps over whole clusters such as Thai consonants with their marks; Thai typed in a font without Thai falls back to a font made for Thai; earlier: Proportional Metrics in vertical type, `vpal`, #966; Cmd+Shift+C aligns centre off the Mac, a double-click on area type's bottom handle turns on Auto Size, #1940; MCP `add_text` exposes the existing `vertical` option for point, area and path type; horizontal remains the default; scores and hours unchanged; Vertical fullwidth question and exclamation marks keep their nominal glyph upright when the font has no vertical alternate; scores and hours unchanged. tab leaders are drawn in the tab's gap, #1877; type in symbols, pattern tiles, graph designs and opacity masks gets its layout bounds back on opening a native file, #1738; score unchanged; Escape while typing ends the edit, #1686; Select › Same on type, #1737; `justify` when creating point type, #1748; scores unchanged; OpenType stylistic sets, alternates, figure styles, superscript and subscript as character features, #1607; a wide word in non-rectangular area type moves down, #1615; scores unchanged; Character Styles New/Redefine capture the first selected character at run boundaries and end prior typing before capture; boundary and typing-history input tests and full workspace CI pass; scores and hours unchanged; Character styles retain explicit Auto leading, propagate resets and preserve local leading overrides; scores and hours unchanged; Linux font folders from fontconfig, #1529; commands and MCP `add_text` report area type that does not fit its frame, #1471; Tabs panel stop drags, #1458; Fit Headline in a frame one line tall, #1444; frames and paths beyond a billion points hold no text, #1451; scores unchanged; missing glyphs are looked for again after a font rescan, #1376; scores unchanged; Full-name font matching (#1258); Windows font-service QA pending; scores unchanged; Middle Eastern digit types: Character panel menu › Digits, `{digits}`; the font menu's script filter lists Thai fonts; Thai, Lao, Khmer and Myanmar lines break between words; the caret steps over whole clusters such as Thai consonants with their marks; Thai typed in a font without Thai falls back to a font made for Thai; earlier: Proportional Metrics in vertical type, `vpal`, #966) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
Type is Illustrator's largest single area by use (weight 13 of 105 across "Type core" and "Type advanced" in
|
||||
[target-app-parity.md](target-app-parity.md)). This checklist lists the features one by one. Status is from the
|
||||
@@ -58,6 +58,8 @@ Character Styles menu New/Redefine and footer New capture the first selected cha
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-14 | minor | Cmd+Shift+C (Align center) works on Windows and Linux too, where egui reported it as a copy (#1940); scores and hours unchanged |
|
||||
| 2026-10-14 | minor | Cmd+Shift+C (Align center) works on Windows and Linux too, where egui reported it as a copy; a double-click on area type's bottom middle handle turns on Auto Size (#1940); scores and hours unchanged |
|
||||
| 2026-10-14 | minor | MCP `add_text` exposes the existing `vertical` option for point, area and path type; horizontal remains the default; scores and hours unchanged. |
|
||||
| 2026-10-14 | minor | Vertical fullwidth question and exclamation marks keep their nominal glyph upright when the font has no vertical alternate; scores and hours unchanged. |
|
||||
| 2026-10-14 | minor | Tab leaders are drawn: the leader's characters fill the tab's gap in the tab's font and size, whole copies on a grid from the frame's edge so leaders line up across lines (fixes #1877); scores and hours unchanged |
|
||||
|
||||
Reference in New Issue
Block a user