feat(annotative): synthesize per-object contexts + editable UI
Make objects genuinely annotative — carrying real per-scale representations that interoperate with other CAD apps — rather than just a native flag. `create_annotation_context` synthesizes the extension-dict chain (AcDbContextDataManager -> ACDB_ANNOTATIONSCALES -> per-scale leaf) from the entity's placement; the editable Annotative toggle now covers Text and block references as well as MText/MLeader; and a new "Annotation Object Scale" dialog (OBJECTSCALE) adds/removes an object's per-scale memberships. Requires the acadrust ObjectContextData encoder (Cargo.lock bump). Also fixes a render bug where objects carrying an *empty* ACDB_ANNOTATIONSCALES (a single-representation marker with no per-scale reps) were treated as annotative and (mis)scaled by the annotation factor in scaled paper viewports, ballooning the text: an object is now annotative-by-context only when its scale collection is non-empty, so such objects render at their base geometry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
31d3023167
commit
c0844ad55c
14 changed files with 922 additions and 30 deletions
|
|
@ -1574,6 +1574,7 @@ impl OpenCADStudio {
|
|||
LayerDeleteWarning => (440, 200),
|
||||
Aliases => (480, 520),
|
||||
ScaleManager => (520, 360),
|
||||
AnnoObjectScale => (360, 420),
|
||||
};
|
||||
Some((w as f32 + EXTRA_W, h as f32 + EXTRA_H))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,52 @@ impl OpenCADStudio {
|
|||
360,
|
||||
)
|
||||
}
|
||||
super::super::ModalKind::AnnoObjectScale => {
|
||||
let tab = &self.tabs[self.active_tab];
|
||||
let entity = self.anno_object_scale_target;
|
||||
// Which scales the object currently has a representation for.
|
||||
let members: Vec<acadrust::types::Handle> = entity
|
||||
.map(|h| {
|
||||
crate::scene::annotative::object_scale_memberships(
|
||||
&tab.scene.document,
|
||||
h,
|
||||
)
|
||||
.into_iter()
|
||||
.map(|(_, sh)| sh)
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let label = entity
|
||||
.and_then(|h| tab.scene.document.get_entity(h))
|
||||
.map(|e| match e {
|
||||
acadrust::EntityType::Text(_) => "TEXT",
|
||||
acadrust::EntityType::MText(_) => "MTEXT",
|
||||
acadrust::EntityType::Insert(_) => "BLOCK",
|
||||
acadrust::EntityType::MultiLeader(_) => "MULTILEADER",
|
||||
_ => "OBJECT",
|
||||
})
|
||||
.unwrap_or("—");
|
||||
let scales: Vec<(String, String, bool)> = tab
|
||||
.scene
|
||||
.scale_list()
|
||||
.into_iter()
|
||||
.map(|(name, _, _)| {
|
||||
let sh = tab.scene.scale_object_handle(&name);
|
||||
let ratio = tab
|
||||
.scene
|
||||
.scale_paper_drawing(&name)
|
||||
.map(|(p, d)| format!("{p}:{d}"))
|
||||
.unwrap_or_default();
|
||||
let is_member = sh.map(|h| members.contains(&h)).unwrap_or(false);
|
||||
(name, ratio, is_member)
|
||||
})
|
||||
.collect();
|
||||
sized(
|
||||
crate::ui::style::anno_object_scale::view_window(&label, &scales),
|
||||
360,
|
||||
420,
|
||||
)
|
||||
}
|
||||
super::super::ModalKind::Plotstyle => sized(
|
||||
crate::ui::style::plotstyle::view_window(
|
||||
self.active_plot_style.as_ref(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue