Edit sketch text content and placement from its outlines (#253)

* Expose interactive editing and placement of sketch text

* Respect document units when editing sketch text

* Route Edit Text through the shared feature dialog

The sketch text editor is now a Kind::Text dialog opened through
Dialog::for_command (frame.rs docking, standard OK/Cancel, Enter/Esc).
Its fields are ordinary dialog fields: they take expressions, parameters
and units, and bare lengths are in the design's units. Untouched fields
keep their exact saved values. The dialog stays open across unrelated
design changes and closes only when its text is gone, the sketch ends,
or another command starts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT

---------

Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-10-12 10:08:15 -04:00
1 parent 62847173f4
commit f77da83c93
7 files changed
+461 -2

No files matched your search

+12
View File
@@ -125,6 +125,12 @@ fn marks(app: &SolveApp, painter: &egui::Painter, proj: &Proj) {
/// Commands that start with a step of their own: Canvas and Decal ask for the image first,
/// Edit Canvas opens the canvas panel. False when the command should not go on.
pub fn start_hook(app: &mut SolveApp, id: &str) -> bool {
if id == "sketch.edit_text"
&& let Some(dialog) = crate::dialogs::Dialog::for_command(app, id)
{
app.dialog = Some(dialog);
return false;
}
// Surface analyses toggle: a second click turns the same one off.
use solvecraft_engine::SurfaceAnalysis as A;
let same = match (id, app.session.analysis) {
@@ -349,6 +355,7 @@ fn mode(id: &str) -> Option<Mode> {
"sketch.slot.arc_three_point" | "sketch.slot.arc_center" => Mode::Points(4),
"sketch.spline.fit_point" | "sketch.spline.control_point" | "sketch.spline.control_point_5" => Mode::Points(0),
"sketch.text" => Mode::Points(1),
"sketch.edit_text" => Mode::Entities(1),
"sketch.blend_curve" => Mode::Points(2),
"sketch.offset" => Mode::Entities(1),
"sketch.fillet" | "sketch.chamfer.equal_distance" | "sketch.chamfer.distance_angle" | "sketch.chamfer.two_distance" => Mode::Entities(1),
@@ -406,6 +413,7 @@ pub fn hint(id: &str) -> Option<String> {
"sketch.spline.fit_point" => "Spline: click fit points; click the start to close smoothly, or right-click to finish",
"sketch.spline.control_point" | "sketch.spline.control_point_5" => "Control point spline: click control points; right-click to finish",
"sketch.text" => "Text: click where the text starts",
"sketch.edit_text" => "Edit Text: click an outline of the text to edit",
"sketch.blend_curve" => "Blend curve: click the ends of two curves",
"sketch.offset" => "Offset: click a curve (its chain is offset), then the side and distance",
"sketch.fillet" => "Fillet: click the corner of two lines",
@@ -730,6 +738,10 @@ pub fn on_click(app: &mut SolveApp, tool: &mut Tool, proj: &Proj, pos: Pos2) {
return;
}
let Some((id, _)) = sketch_entity(app, &hits) else { return };
if cmd == "sketch.edit_text" {
crate::sketch_text::open(app, &id);
return;
}
if cmd == "sketch.centerline" {
let _ = app.run(cmd, json!({"curves": [id]}));
return;