forked from 1b-agent/opencadstudio-upstream
feat(blocks): implement Block Definition dialog (BLOCK/BMAKE) with on-screen sequencing
Implement the complete Block Definition dialog window launched via BLOCK
and BMAKE commands, featuring standard CAD layout, workflows, and entity
creation pipelines.
- Dialog UI & Layout:
- 2-column compact CAD grid with synchronized vertical heights (580 × 390px).
- Editable combobox with existing block names, invalid character validation,
and inline redefinition badge.
- Multi-line text editor widget for block descriptions (replacing single-line input).
- Quick Select (QSELECT) button integration restoring dialog state upon completion.
- Confirmation guard when attempting to redefine an existing block definition.
- Centered radio buttons, clean coordinate inputs, and accessible keyboard shortcuts.
- Base Point & On-Screen Workflow:
- BlockOnScreenCommand strictly enforces prompt sequencing: Base point is
prompted before object selection.
- Dynamically recalculates world_to_block and block_to_world affine transforms
when base point is specified on-screen, preventing stale (0,0,0) normalization.
- Supports Retain, Convert to block (INSERT placement), and Delete modes.
- Explode Enforcement:
- Guarded EXPLODE command to prevent decomposing blocks flagged as non-explodable.
- Dynamic Themed Icons:
- Added pick_point.svg, select_objects.svg, quick_select.svg, and warning_triangle.svg.
- Routed all icons through the semantic theming engine so line work (#B4B6B9)
and accents (#6DB7ED) adapt automatically to the active theme.
- Tests:
- Added unit tests for retain/convert/delete modes, redefinition, explodable flag,
on-screen base point transform recalculation, and command sequencing.
This commit is contained in:
1 parent
889a19c362
commit
652f4d6bbc
19 files changed
+2316
-318
No files matched your search
@@ -98,11 +98,20 @@ pub fn explode_entity(entity: &EntityType, document: &CadDocument) -> Vec<Entity
|
||||
{
|
||||
vec![]
|
||||
}
|
||||
EntityType::Insert(ins) => ins
|
||||
.explode_from_document(document)
|
||||
.into_iter()
|
||||
.map(normalize_insert_entity)
|
||||
.collect(),
|
||||
EntityType::Insert(ins) => {
|
||||
let explodable = document
|
||||
.block_records
|
||||
.get(&ins.block_name)
|
||||
.map_or(true, |br| br.explodable);
|
||||
if !explodable {
|
||||
vec![]
|
||||
} else {
|
||||
ins.explode_from_document(document)
|
||||
.into_iter()
|
||||
.map(normalize_insert_entity)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
EntityType::MLine(ml) => explode_mline(ml),
|
||||
EntityType::Dimension(dim) => explode_dimension(dim, document),
|
||||
_ => vec![],
|
||||
@@ -1500,6 +1509,18 @@ mod tests {
|
||||
assert!(explode_entity(&EntityType::Insert(insert), &doc).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexplodable_block_is_not_exploded() {
|
||||
let mut doc = CadDocument::new();
|
||||
let mut block = acadrust::tables::BlockRecord::new("NO_EXPLODE");
|
||||
block.handle = doc.allocate_handle();
|
||||
block.explodable = false;
|
||||
doc.block_records.add(block).unwrap();
|
||||
|
||||
let insert = acadrust::entities::Insert::new("NO_EXPLODE", Vector3::new(0.0, 0.0, 0.0));
|
||||
assert!(explode_entity(&EntityType::Insert(insert), &doc).is_empty());
|
||||
}
|
||||
|
||||
/// A dimension created without a geometry block gets a real `*D` block on
|
||||
/// bake, its `block_name` resolves to that block, and a second bake is a
|
||||
/// no-op (already has a valid block).
|
||||
|
||||
Reference in new issue
Block a user