feat: complete freehand sketch workflow

Co-authored-by: ramox81 <184937705+ramox81@users.noreply.github.com>
This commit is contained in:
Hakan Sevenandramox81 committed 2026-08-21 00:17:44 +03:00
commit 464971969c
32 files changed
+926 -113

No files matched your search

+21
View File
@@ -642,6 +642,26 @@ impl OpenCADStudio {
/// Pure-selection commands (SELECTALL, QSELECT, …) run without an active
/// command, so `was_active` is false and their selection is preserved.
pub(super) fn apply_cmd_result(&mut self, result: CmdResult) -> Task<Message> {
let settings = self.tabs[self.active_tab]
.active_cmd
.as_ref()
.and_then(|command| command.sketch_settings());
if let Some((sketch_type, increment, tolerance)) = settings {
let tab = &mut self.tabs[self.active_tab];
let changed = tab.scene.document.header.sketch_type != sketch_type
|| (tab.scene.document.header.sketch_increment - increment).abs() > f64::EPSILON
|| (tab.scene.document.header.sketch_tolerance - tolerance).abs()
> f64::EPSILON;
if changed {
crate::io::set_sketch_settings(
&mut tab.scene.document,
sketch_type,
increment,
tolerance,
);
tab.dirty = true;
}
}
let was_active = self.tabs[self.active_tab].active_cmd.is_some();
let preserve_selection =
matches!(result, CmdResult::Relaunch(..) | CmdResult::Dispatch(..));
@@ -785,6 +805,7 @@ impl OpenCADStudio {
self.commit_entity(entity);
}
self.tabs[i].dirty = true;
self.tabs[i].scene.clear_preview_wire();
let prompt = self.tabs[i].active_cmd.as_ref().map(|c| c.prompt());
if let Some(p) = prompt {
self.command_line.push_info(&p);
+6 -1
View File
@@ -487,7 +487,12 @@ impl OpenCADStudio {
"SKETCH" => {
use crate::modules::draw::draw::sketch::SketchCommand;
let new_cmd = SketchCommand::new();
let header = &self.tabs[i].scene.document.header;
let new_cmd = SketchCommand::new(
header.sketch_type,
header.sketch_increment,
header.sketch_tolerance,
);
self.command_line.push_info(&new_cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
}
+2
View File
@@ -526,6 +526,8 @@ inventory::submit!(crate::command::CommandRegistration {
"HALOGAP",
"TRACEWID",
"SKETCHINC",
"SKPOLY",
"SKTOLERANCE",
// Reset selected entities' overrides to follow their layer.
"SETBYLAYER",
// Remove duplicate objects; set drawing base point; audit integrity;
+35 -7
View File
@@ -931,6 +931,8 @@ impl OpenCADStudio {
| "HALOGAP"
| "TRACEWID"
| "SKETCHINC"
| "SKPOLY"
| "SKTOLERANCE"
) =>
{
return self.dispatch_styleprops(&format!("SETVAR {cmd}"), i);
@@ -953,7 +955,7 @@ impl OpenCADStudio {
let value = it.next().map(|s| s.trim().to_string());
if name.is_empty() || name == "?" {
self.command_line.push_info(
"SETVAR: LTSCALE CELTSCALE PDMODE PDSIZE TEXTSIZE ORTHOMODE FILLMODE MIRRTEXT FRAME IMAGEFRAME PDFFRAME WIPEOUTFRAME XCLIPFRAME POINTCLOUDCLIPFRAME ZOOMWHEEL ZOOMFACTOR CURSORSIZE PICKBOX CURSORTYPE SNAPANG ATTREQ ATTDIA DIMASSOC ANGBASE ANGDIR | CLAYER CELTYPE TEXTSTYLE (read-only)",
"SETVAR: LTSCALE CELTSCALE PDMODE PDSIZE TEXTSIZE ORTHOMODE FILLMODE MIRRTEXT FRAME IMAGEFRAME PDFFRAME WIPEOUTFRAME XCLIPFRAME POINTCLOUDCLIPFRAME ZOOMWHEEL ZOOMFACTOR CURSORSIZE PICKBOX CURSORTYPE SNAPANG ATTREQ ATTDIA DIMASSOC ANGBASE ANGDIR SKETCHINC SKPOLY SKTOLERANCE | CLAYER CELTYPE TEXTSTYLE (read-only)",
);
} else {
let frame_kind = crate::scene::frame::kind_for_name(&name);
@@ -1700,15 +1702,41 @@ impl OpenCADStudio {
None => Ok((format!("TRACEWID = {}", h.trace_width), false)),
},
"SKETCHINC" => match &value {
Some(v) => v
.parse::<f64>()
.map(|x| {
Some(v) => match v.parse::<f64>() {
Ok(x) if x.is_finite() && x > 0.0 => {
let changed = h.sketch_increment != x;
h.sketch_increment = x;
(format!("SKETCHINC = {x}"), true)
})
.map_err(|_| "SETVAR: numeric value required.".into()),
Ok((format!("SKETCHINC = {x}"), changed))
}
_ => Err("SETVAR: positive numeric value required.".into()),
},
None => Ok((format!("SKETCHINC = {}", h.sketch_increment), false)),
},
"SKPOLY" => match &value {
Some(v) => match v.parse::<i16>() {
Ok(x @ 0..=2) => {
let changed = h.sketch_type != x;
h.sketch_type = x;
Ok((format!("SKPOLY = {x}"), changed))
}
_ => Err("SETVAR: integer value from 0 to 2 required.".into()),
},
None => Ok((format!("SKPOLY = {}", h.sketch_type), false)),
},
"SKTOLERANCE" => match &value {
Some(v) => match v.parse::<f64>() {
Ok(x) if x.is_finite() && (0.0..=1.0).contains(&x) => {
let changed = h.sketch_tolerance != x;
h.sketch_tolerance = x;
Ok((format!("SKTOLERANCE = {x}"), changed))
}
_ => Err("SETVAR: numeric value from 0 to 1 required.".into()),
},
None => Ok((
format!("SKTOLERANCE = {}", h.sketch_tolerance),
false,
)),
},
"CLAYER" => match &value {
Some(_) => Err(
"SETVAR: CLAYER is read-only here — use the CLAYER command."