fix(sketch): move and copy editable text as a whole source (#715)

Dragging a text outline now moves the whole editable text, and Move/Copy shifts or rotates it as one piece (a copy stays independently editable). Content, font, height and outline identities are kept; a drag is one undo step and Esc restores the start.
This commit is contained in:
selune authored and GitHub committed 2026-10-13 10:29:02 -04:00
1 parent 2c4d197bf4
commit 11084a5963
14 files changed
+469 -9

No files matched your search

+12 -2
View File
@@ -247,6 +247,7 @@ pub enum Kind {
Part(crate::dialogs_parts::Pt),
/// Edit Text: a sketch text's content and placement (`sketch_text`).
Text(crate::sketch_text::Tx),
TextMove(crate::sketch_text_move::TextMove),
}
/// The rest of the Hole dialog: placement, extents, tap type and drill point.
@@ -503,7 +504,8 @@ impl Dialog {
.or_else(|| crate::dialogs_appearance::start(app, id))
.or_else(|| crate::dialogs_motion::start(app, id))
.or_else(|| crate::dialogs_parts::start(app, id))
.or_else(|| crate::sketch_text::start(app, id))?;
.or_else(|| crate::sketch_text::start(app, id))
.or_else(|| crate::sketch_text_move::start(app, id))?;
Dialog::new(kind, inputs)
}
};
@@ -933,6 +935,7 @@ fn title(k: &Kind) -> &'static str {
Kind::Motion(k) => k.title(),
Kind::Part(_) => "INSERT PART",
Kind::Text(_) => "EDIT TEXT",
Kind::TextMove(_) => "MOVE/COPY TEXT",
}
}
@@ -1354,6 +1357,11 @@ pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
return;
}
let _language = crate::i18n::scope(&app.preferences.language);
if let Kind::TextMove(k) = &d.kind
&& !crate::sketch_text_move::valid(app, k)
{
return;
}
auto_operation(app, &mut d);
update_measure(app, &mut d);
update_fill_cells(app, &mut d);
@@ -2061,6 +2069,7 @@ pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
Kind::Motion(k) => enter |= crate::dialogs_motion::rows(app, ui, k, &mut d.inputs),
Kind::Part(k) => enter |= crate::dialogs_parts::rows(app, ui, k, &d.inputs),
Kind::Text(k) => enter |= crate::sketch_text::rows(ui, k),
Kind::TextMove(k) => enter |= crate::sketch_text_move::rows(ui, k),
Kind::ConfirmDelete { with, fail, .. } => {
if !with.is_empty() {
row_label(ui, "Also deletes");
@@ -2171,7 +2180,7 @@ pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
crate::dialogs_motion::closed(app, &mut d, applied);
}
// The edited text's outlines are new curves: the old selection would name stale ids.
if applied && matches!(d.kind, Kind::Text(_)) {
if applied && matches!(d.kind, Kind::Text(_) | Kind::TextMove(_)) {
let _ = app.session.execute("select.clear", &json!({}));
}
if keep && !cancel {
@@ -3067,6 +3076,7 @@ fn dialog_commands(app: &SolveApp, d: &Dialog) -> Result<Vec<(String, Value)>, S
Kind::Motion(k) => return crate::dialogs_motion::commands(app, k, &d.inputs),
Kind::Part(k) => return crate::dialogs_parts::commands(app, k, &d.inputs),
Kind::Text(k) => return crate::sketch_text::commands(app, k),
Kind::TextMove(k) => return crate::sketch_text_move::commands(app, k),
};
let mut params = params;
if let Value::Object(m) = &mut params {