feat(hatch): HPASSOC sets whether new hatches are associative

HPASSOC (0 or 1, default 1) is the starting state of the hatch
command's associative option. It is an application setting: typed
directly or through SETVAR, it persists across sessions and does not
mark the drawing modified.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-10-13 15:32:55 +03:00
1 parent dd45ac4039
commit 2ddf2a31da
6 files changed
+29 -1

No files matched your search

+2 -1
View File
@@ -764,7 +764,8 @@ impl OpenCADStudio {
});
let new_cmd =
HatchCommand::new(outlines, boundary_sources, selected, inherited, plane)
.with_origin(self.tabs[i].scene.document.hatch_origin());
.with_origin(self.tabs[i].scene.document.hatch_origin())
.with_associative(self.hatch_associative);
self.command_line.push_info(&new_cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
self.refresh_area_preview(i);
+13
View File
@@ -1148,6 +1148,7 @@ impl OpenCADStudio {
| "SHORTCUTMENUDURATION"
| "CURSORSIZE"
| "PICKBOX"
| "HPASSOC"
| "CURSORTYPE"
| "SNAPANG"
| "TEXTFILL"
@@ -2188,6 +2189,17 @@ impl OpenCADStudio {
},
None => Ok((format!("PICKBOX = {}", self.pick_box), false)),
},
"HPASSOC" => match value.as_deref() {
Some(v @ ("0" | "1")) => {
self.hatch_associative = v == "1";
Ok((format!("HPASSOC = {v}"), true))
}
Some(_) => Err("SETVAR: 0 or 1 required.".into()),
None => Ok((
format!("HPASSOC = {}", u8::from(self.hatch_associative)),
false,
)),
},
"CURSORTYPE" => match &value {
Some(v) => match v.as_str() {
"0" => {
@@ -3134,6 +3146,7 @@ impl OpenCADStudio {
| "SHORTCUTMENUDURATION"
| "CURSORSIZE"
| "PICKBOX"
| "HPASSOC"
| "CURSORTYPE"
| "SNAPANG"
| "CLIPROMPTLINES"
+3
View File
@@ -640,6 +640,8 @@ pub(super) struct OpenCADStudio {
cursor_size: i32,
/// Selection-box size setting (PICKBOX, 0..=50).
pick_box: i32,
/// HPASSOC: new hatches follow their boundary objects.
hatch_associative: bool,
/// Use REFEDIT rather than BEDIT when double-clicking an attribute-free block.
double_click_block_refedit: bool,
/// Open ATTEDIT when double-clicking a block with attributes.
@@ -4534,6 +4536,7 @@ impl OpenCADStudio {
zoom_factor_input: 60.to_string(),
cursor_size: 5,
pick_box: 3,
hatch_associative: true,
double_click_block_refedit: false,
double_click_block_attedit: true,
right_click_mode: settings::RightClickMode::ShortcutMenu,
+3
View File
@@ -398,6 +398,8 @@ pub struct UserSettings {
pub cursor_size: i32,
/// PICKBOX: normalized visible-box and click-aperture size.
pub pick_box: i32,
/// HPASSOC: new hatches follow their boundary objects.
pub hatch_associative: bool,
/// When true, double-clicking a block reference starts REFEDIT instead of BEDIT.
pub double_click_block_refedit: bool,
/// When true, double-clicking a block with attributes opens ATTEDIT.
@@ -829,6 +831,7 @@ impl Default for UserSettings {
zoom_factor: 60,
cursor_size: 5,
pick_box: 3,
hatch_associative: true,
options_tab: crate::ui::window::options::OptionsTab::General,
show_viewcube: true,
show_ucs_icon: true,
+2
View File
@@ -780,6 +780,7 @@ impl OpenCADStudio {
zoom_factor: self.zoom_factor,
cursor_size: self.cursor_size,
pick_box: self.pick_box,
hatch_associative: self.hatch_associative,
options_tab: self.options_tab,
show_viewcube: self.show_viewcube,
show_ucs_icon: self.show_ucs_icon,
@@ -891,6 +892,7 @@ impl OpenCADStudio {
self.zoom_factor_input = self.zoom_factor.to_string();
self.cursor_size = s.cursor_size.clamp(1, 100);
self.pick_box = s.pick_box.clamp(0, 50);
self.hatch_associative = s.hatch_associative;
self.options_tab = s.options_tab;
self.spacemouse_preferences = s.spacemouse;
// These four drive real features with commands and status-bar pills,
+6
View File
@@ -248,6 +248,12 @@ impl HatchCommand {
command
}
/// HPASSOC: whether the hatch starts out associative.
pub fn with_associative(mut self, associative: bool) -> Self {
self.associative = associative;
self
}
pub fn with_origin(mut self, origin: [f64; 2]) -> Self {
self.default_origin = origin;
self