mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-31 05:07:51 -06:00
Type: input method composition (Japanese IME) in the Type tool
Typing with an input method (the macOS Japanese IME and the like) used to insert the raw keys (romaji came in as ASCII): egui's Ime events weren't handled. - Tools gain `ime_preedit` / `composing` / `ime_caret`; the Type tool lays the marked text out in place inside its typing session, underlined (the clause being converted thicker), and commits it through `text_input`. Character ranges from the IME convert to byte ranges in one place. A cancelled composition leaves no empty undo step; an empty clear with nothing marked never deletes the selection. - The UI sends Text and Ime events to the tool in order, sends IMEOutput every frame while text is edited (what lets egui-winit enable the IME and place its candidate window at the caret, or the converting clause), and holds back keys, Enter/Escape, clipboard, single-key shortcuts and menu commands (Undo, Cut, Select All… also from the native menu) while composing. A click, a tool switch or a style change ends the composition with the marked text kept as typed; on macOS the IME is told to discard it (NSTextInputContext.discardMarkedText) so it doesn't come back in the next input. - Undo during a typing session also ends the Type tool's session, so its caret and marked text follow the document. - Tests: tools (char → byte ranges, underlines and candidate position), engine (compose → commit is one step, cancel leaves no step, a click commits, Undo mid-composition is safe), ui-egui (synthetic Ime events: compose, commit, ⌘Z held back, IME output, click and app switch). Checked by hand on macOS 27 with the Japanese IME (romaji input, convert, commit, cancel, Undo/Redo after commit, click away, Latin mode, app switch). Not checked: Windows and Linux IMEs, the web build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7a39cb7b89
commit
66fa0a998a
@@ -116,10 +116,21 @@ fn set_units(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
ok()
|
||||
}
|
||||
|
||||
/// A typing session in progress (the Type tool previews the whole session as one interaction).
|
||||
fn typing_in_progress(s: &Session) -> bool {
|
||||
s.active().and_then(|d| d.interaction.as_ref()).is_some_and(|it| it.label == "Typing" && it.preview.is_some())
|
||||
}
|
||||
|
||||
fn undo(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
// What is still in progress (typing, a drag) is the step to undo: keep it first, so Undo takes
|
||||
// back only that and Redo brings it back, instead of dropping it and undoing the step before.
|
||||
// A typing session also ends in the Type tool, whose caret and marked text (IME) must follow
|
||||
// the document.
|
||||
let typing = typing_in_progress(s);
|
||||
s.commit_interaction()?;
|
||||
if typing {
|
||||
s.set_tool_option("endTyping", &Value::Bool(true));
|
||||
}
|
||||
let st = s.doc_mut()?;
|
||||
let e = st.history.undo.pop().ok_or_else(|| EngineError::Other("nothing to undo".into()))?;
|
||||
let label = e.label.clone();
|
||||
|
||||
Reference in New Issue
Block a user