feat: node graph overlay; move to opencadcodec/opencadkernel/opencadgraph

The codec and kernel repositories and crates are renamed opencadcodec and
opencadkernel. Inside OCS they are depended on under short keys, so code
reads `codec::`, `kernel::` and the new `graph::` (opencadgraph, the node
graph engine). File-format and protocol spellings stay as they were: the
ACIS product id `acadrust`, the ACADRUST_* switches and the plugin
version keys `acadrust_version` / `acadrust_source`.

A button left of MCP on the command line opens a translucent node graph
over the viewport, with a palette of object, input, math, logic, list,
text and geometry nodes added by click or drag. An object node owns
drawing entities and its rows are the Properties panel's own rows for
them: the single-object page is extracted from refresh_properties as
entity_property_sections, values use the control protocol's
property_json, and writes go through set_property_value with a property
target override, so the panel, MCP and the graph share one read/write
path. A list reaching an object row makes one entity per element. Each
graph action is one undo step; the canvas pans and zooms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-09-25 07:34:23 +03:00
1 parent 56c04408d6
commit f537aff75c
430 files changed
+9925 -8540

No files matched your search

+103 -103
View File
@@ -21,8 +21,8 @@ use crate::scene::{
};
use crate::ui::PropertiesPanel;
use crate::ui::window::attribute_editor::{AttrRow, AttrTab};
use acadrust::types::Color as AcadColor;
use acadrust::{EntityType as AcadEntityType, Handle};
use codec::types::Color as AcadColor;
use codec::{EntityType as AcadEntityType, Handle};
use iced::time::Instant;
use iced::{mouse, Point, Task};
@@ -1233,7 +1233,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// Toggle frozen_layers on the viewport entity
for e in self.tabs[i].scene.document.entities_mut() {
if let acadrust::EntityType::Viewport(vp) = e {
if let codec::EntityType::Viewport(vp) = e {
if vp.common.handle == vp_handle {
if vp.frozen_layers.contains(&layer_handle) {
vp.frozen_layers.retain(|h| h != &layer_handle);
@@ -1271,7 +1271,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
n += 1;
};
self.push_undo_snapshot(i, "LAYER NEW");
use acadrust::tables::layer::Layer as DocLayer;
use codec::tables::layer::Layer as DocLayer;
// A layer needs a real handle or it is dropped on a DWG save
// (the format is handle-based; issue #67).
let mut dl = DocLayer::new(&new_name);
@@ -1370,7 +1370,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
return Task::none();
};
self.push_undo_snapshot(i, "LAYER DELETE");
let handles: Vec<acadrust::Handle> = self.tabs[i]
let handles: Vec<codec::Handle> = self.tabs[i]
.scene
.document
.entities()
@@ -1448,7 +1448,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.layers
.get(&name)
.map(|l| l.handle)
.unwrap_or(acadrust::types::Handle::NULL);
.unwrap_or(codec::types::Handle::NULL);
self.tabs[i].scene.document.header.current_layer_name = name.clone();
self.tabs[i].scene.document.header.current_layer_handle = handle;
self.tabs[i].active_layer = name.clone();
@@ -1508,7 +1508,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
) {
let is_dimension = matches!(
self.tabs[i].scene.document.get_entity(popup.handle),
Some(acadrust::EntityType::Dimension(_))
Some(codec::EntityType::Dimension(_))
);
if is_dimension {
let movement = match item.action {
@@ -1544,7 +1544,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// Only multileaders use the whole-object grip.
let is_multileader = matches!(
self.tabs[i].scene.document.get_entity(popup.handle),
Some(acadrust::EntityType::MultiLeader(_))
Some(codec::EntityType::MultiLeader(_))
);
let (grip_id, is_translate) =
if matches!(item.action, GripMenuAction::MoveWithLeader)
@@ -1722,7 +1722,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// structural, so it can't ride the in-place apply below.
if matches!(item.action, GripMenuAction::BreakVertex) {
let pieces = match self.tabs[i].scene.document.get_entity(popup.handle) {
Some(acadrust::EntityType::LwPolyline(p)) => {
Some(codec::EntityType::LwPolyline(p)) => {
crate::entities::lwpolyline::break_at_vertex(p, popup.grip_id)
}
_ => None,
@@ -1839,12 +1839,12 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.document
.get_entity(popup.handle)
.is_some_and(|entity| match (item.action, entity) {
(GripMenuAction::ShowFit, acadrust::EntityType::Spline(spline)) => {
(GripMenuAction::ShowFit, codec::EntityType::Spline(spline)) => {
crate::entities::spline::shows_fit_points(spline)
}
(
GripMenuAction::ShowControlVertices,
acadrust::EntityType::Spline(spline),
codec::EntityType::Spline(spline),
) => {
crate::entities::spline::shows_control_vertices(spline)
}
@@ -1862,7 +1862,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.document
.get_entity(popup.handle)
.and_then(|e| match e {
acadrust::EntityType::MultiLeader(ml) => Some(
codec::EntityType::MultiLeader(ml) => Some(
ml.context
.leader_roots
.iter()
@@ -2089,7 +2089,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.layers
.get(&layer)
.map(|l| l.handle)
.unwrap_or(acadrust::types::Handle::NULL);
.unwrap_or(codec::types::Handle::NULL);
self.tabs[i].scene.document.header.current_layer_name = layer.clone();
self.tabs[i].scene.document.header.current_layer_handle = handle;
self.tabs[i].active_layer = layer.clone();
@@ -2161,7 +2161,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.iter()
.find(|x| x.name.eq_ignore_ascii_case(&lt))
.map(|x| x.handle)
.unwrap_or(acadrust::types::Handle::NULL);
.unwrap_or(codec::types::Handle::NULL);
self.tabs[i].scene.document.header.current_linetype_name = lt.clone();
self.tabs[i].scene.document.header.current_linetype_handle = handle;
self.tabs[i].dirty = true;
@@ -2244,7 +2244,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
if let Some(entry) = hatch_patterns::find(&name) {
self.push_undo_snapshot(i, "HATCHEDIT");
for &handle in &handles {
if let Some(acadrust::EntityType::Hatch(dxf)) =
if let Some(codec::EntityType::Hatch(dxf)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
let mut pattern = hatch_patterns::build_dxf_pattern(entry);
@@ -2268,7 +2268,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
crate::scene::model::hatch_model::HatchPattern::Solid
);
dxf.pattern_type =
acadrust::entities::HatchPatternType::Predefined;
codec::entities::HatchPatternType::Predefined;
dxf.gradient_color.enabled = false;
}
if let Some(model) = self.tabs[i].scene.hatches.get_mut(&handle) {
@@ -2304,12 +2304,12 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
};
let document = &self.tabs[i].scene.document;
let (toggle, current) = match document.get_entity(handle) {
Some(acadrust::EntityType::MText(text)) => ("is_annotative", text.is_annotative),
Some(codec::EntityType::MText(text)) => ("is_annotative", text.is_annotative),
Some(entity) => (
"annotative_ctx",
crate::scene::annotative::is_annotative(document, entity)
|| match entity {
acadrust::EntityType::Dimension(dimension) => {
codec::EntityType::Dimension(dimension) => {
crate::scene::annotative::dim_style_is_annotative(
document,
&dimension.base().style_name,
@@ -2339,7 +2339,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
) {
let unchanged = handles.iter().all(|handle| {
match self.tabs[i].scene.document.get_entity(*handle) {
Some(acadrust::EntityType::Spline(spline)) => match field {
Some(codec::EntityType::Spline(spline)) => match field {
"spline_method" => {
value
== if crate::entities::spline::shows_fit_points(spline) {
@@ -2367,7 +2367,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
}
_ => false,
},
Some(acadrust::EntityType::Hatch(hatch)) => match field {
Some(codec::EntityType::Hatch(hatch)) => match field {
"fill_type" => {
value
== if hatch.gradient_color.is_single_color {
@@ -2386,21 +2386,21 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
"style" => {
value
== match hatch.style {
acadrust::entities::HatchStyleType::Normal => "Normal",
acadrust::entities::HatchStyleType::Outer => "Outer",
acadrust::entities::HatchStyleType::Ignore => "Ignore",
codec::entities::HatchStyleType::Normal => "Normal",
codec::entities::HatchStyleType::Outer => "Outer",
codec::entities::HatchStyleType::Ignore => "Ignore",
}
}
"pattern_type_label" => {
value
== match hatch.pattern_type {
acadrust::entities::HatchPatternType::Predefined => {
codec::entities::HatchPatternType::Predefined => {
"Predefined"
}
acadrust::entities::HatchPatternType::UserDefined => {
codec::entities::HatchPatternType::UserDefined => {
"User Defined"
}
acadrust::entities::HatchPatternType::Custom => "Custom",
codec::entities::HatchPatternType::Custom => "Custom",
}
}
_ => false,
@@ -2428,7 +2428,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.document
.get_entity(handle)
.and_then(|entity| match entity {
acadrust::EntityType::Surface(surface) => Some(
codec::EntityType::Surface(surface) => Some(
crate::entities::solid3d::surface_property_state(surface),
),
_ => None,
@@ -2480,7 +2480,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
}
} else if field == "tol_text_style" {
use crate::entities::dim_override as dov;
use acadrust::xdata::XDataValue;
use codec::xdata::XDataValue;
let style_handle = self.tabs[i]
.scene
.document
@@ -2493,7 +2493,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
if self.tabs[i].scene.is_layer_locked(handle)
|| !matches!(
self.tabs[i].scene.document.get_entity(handle),
Some(acadrust::EntityType::Tolerance(_))
Some(codec::EntityType::Tolerance(_))
)
{
continue;
@@ -2520,7 +2520,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
if self.tabs[i].scene.is_layer_locked(handle) {
continue;
}
if let Some(acadrust::EntityType::Tolerance(tolerance)) =
if let Some(codec::EntityType::Tolerance(tolerance)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
tolerance.dimension_style_handle = Some(style_handle);
@@ -2551,7 +2551,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
}
if matches!(
self.tabs[i].scene.document.get_entity(handle),
Some(acadrust::EntityType::Dimension(_))
Some(codec::EntityType::Dimension(_))
) {
let applied = crate::entities::dim_override::set_property(
&mut self.tabs[i].scene.document,
@@ -2560,8 +2560,8 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
&value,
);
if applied && field == "dim_text_inside" {
if let Some(acadrust::EntityType::Dimension(
acadrust::entities::Dimension::LargeRadial(dimension),
if let Some(codec::EntityType::Dimension(
codec::entities::Dimension::LargeRadial(dimension),
)) = self.tabs[i].scene.document.get_entity_mut(handle)
{
dimension.base.text_user_positioned = false;
@@ -2573,7 +2573,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
for &handle in &handles {
if matches!(
self.tabs[i].scene.document.get_entity(handle),
Some(acadrust::EntityType::Viewport(_))
Some(codec::EntityType::Viewport(_))
) {
let _ = self.tabs[i]
.scene
@@ -2591,7 +2591,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.cloned();
if let Some(ucs) = ucs_data {
for handle in &handles {
if let Some(acadrust::EntityType::Viewport(vp)) =
if let Some(codec::EntityType::Viewport(vp)) =
self.tabs[i].scene.document.get_entity_mut(*handle)
{
vp.ucs_handle = ucs.handle;
@@ -2613,7 +2613,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.cloned();
if let Some(view) = view_data {
for handle in &handles {
if let Some(acadrust::EntityType::Viewport(vp)) =
if let Some(codec::EntityType::Viewport(vp)) =
self.tabs[i].scene.document.get_entity_mut(*handle)
{
vp.view_target = view.target.clone();
@@ -2642,13 +2642,13 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
let resolved_mleader_style = (field == "mleader_style")
.then(|| {
doc.objects.values().find_map(|object| match object {
acadrust::objects::ObjectType::MultiLeaderStyle(style)
codec::objects::ObjectType::MultiLeaderStyle(style)
if style.name == value => Some(style.clone()),
_ => None,
})
})
.flatten();
let resolved: Option<acadrust::Handle> = match field {
let resolved: Option<codec::Handle> = match field {
"mleader_style" => {
resolved_mleader_style.as_ref().map(|style| style.handle)
}
@@ -2698,7 +2698,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
);
style_annotation = Some(style.is_annotative);
}
} else if let Some(acadrust::EntityType::MultiLeader(ml)) =
} else if let Some(codec::EntityType::MultiLeader(ml)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
match field {
@@ -2707,7 +2707,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
ml.text_style_handle = Some(h);
ml.context.text_style_handle = Some(h);
ml.property_override_flags.insert(
acadrust::entities::MultiLeaderPropertyOverrideFlags::TEXT_STYLE,
codec::entities::MultiLeaderPropertyOverrideFlags::TEXT_STYLE,
);
}
}
@@ -2717,12 +2717,12 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
for line in &mut root.lines {
line.arrowhead_handle = resolved;
line.override_flags.insert(
acadrust::entities::LeaderLinePropertyOverrideFlags::ARROWHEAD,
codec::entities::LeaderLinePropertyOverrideFlags::ARROWHEAD,
);
}
}
ml.property_override_flags.insert(
acadrust::entities::MultiLeaderPropertyOverrideFlags::ARROWHEAD,
codec::entities::MultiLeaderPropertyOverrideFlags::ARROWHEAD,
);
}
"line_type_handle" => {
@@ -2731,12 +2731,12 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
for line in &mut root.lines {
line.line_type_handle = resolved;
line.override_flags.insert(
acadrust::entities::LeaderLinePropertyOverrideFlags::LINE_TYPE,
codec::entities::LeaderLinePropertyOverrideFlags::LINE_TYPE,
);
}
}
ml.property_override_flags.insert(
acadrust::entities::MultiLeaderPropertyOverrideFlags::LEADER_LINE_TYPE,
codec::entities::MultiLeaderPropertyOverrideFlags::LEADER_LINE_TYPE,
);
}
"block_content_handle" => {
@@ -2747,7 +2747,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
ml.context.block_content_location =
ml.context.content_base_point;
ml.property_override_flags.insert(
acadrust::entities::MultiLeaderPropertyOverrideFlags::BLOCK_CONTENT,
codec::entities::MultiLeaderPropertyOverrideFlags::BLOCK_CONTENT,
);
}
}
@@ -2780,8 +2780,8 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// reverts to the style); the other two map a label to
// the DIMLWD / DIMTAD enum value.
use crate::entities::dim_override as dov;
use acadrust::xdata::XDataValue;
let arrow_h: Option<acadrust::Handle> =
use codec::xdata::XDataValue;
let arrow_h: Option<codec::Handle> =
if field == "arrow_block" && value != "Closed filled" {
self.tabs[i]
.scene
@@ -2803,7 +2803,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// a multi-type selection can't get stray overrides.
if !matches!(
self.tabs[i].scene.document.get_entity(handle),
Some(acadrust::EntityType::Leader(_))
Some(codec::EntityType::Leader(_))
) {
continue;
}
@@ -2835,7 +2835,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
doc,
handle,
dov::DIMLDRBLK,
Some(XDataValue::Handle(acadrust::Handle::NULL)),
Some(XDataValue::Handle(codec::Handle::NULL)),
);
} else if let Some(h) = arrow_h {
dov::set(
@@ -2871,7 +2871,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
if self.tabs[i].scene.is_layer_locked(handle) {
continue;
}
if let Some(acadrust::EntityType::Insert(ins)) =
if let Some(codec::EntityType::Insert(ins)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
if ins.block_name != canon {
@@ -2894,7 +2894,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.objects
.iter()
.find_map(|(handle, object)| match object {
acadrust::objects::ObjectType::TableStyle(style)
codec::objects::ObjectType::TableStyle(style)
if style.name.eq_ignore_ascii_case(value.trim()) =>
{
Some(*handle)
@@ -2903,7 +2903,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
});
if let Some(style_handle) = style_handle {
for &handle in &handles {
if let Some(acadrust::EntityType::Table(table)) =
if let Some(codec::EntityType::Table(table)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
table.table_style_handle = Some(style_handle);
@@ -2929,7 +2929,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// ACAD_PLOTSTYLENAME dictionary to its placeholder handle.
let dict_h =
self.tabs[i].scene.document.header.acad_plotstylename_dict_handle;
let ph: Option<acadrust::Handle> =
let ph: Option<codec::Handle> =
crate::scene::annotative::as_dict(&self.tabs[i].scene.document, dict_h)
.and_then(|d| {
d.entries
@@ -2970,13 +2970,13 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// Material source: ByLayer / ByBlock clear the handle; a
// named material sets flag 3 + its handle (resolved here
// because the update loop holds the document).
let mat_handle: Option<acadrust::Handle> = self.tabs[i]
let mat_handle: Option<codec::Handle> = self.tabs[i]
.scene
.document
.objects
.iter()
.find_map(|(h, o)| match o {
acadrust::objects::ObjectType::Material(m) if m.name == value => {
codec::objects::ObjectType::Material(m) if m.name == value => {
Some(*h)
}
_ => None,
@@ -3022,7 +3022,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.document
.get_entity(handle)
.and_then(|entity| match entity {
acadrust::EntityType::MLine(mline) => {
codec::EntityType::MLine(mline) => {
crate::entities::mline::resolved_mline_style(
mline,
&self.tabs[i].scene.document,
@@ -3048,7 +3048,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
);
if matches!(field, "ml_justification" | "ml_scale") {
if let (
acadrust::EntityType::MLine(mline),
codec::EntityType::MLine(mline),
Some(style),
) = (entity, mline_style.as_ref())
{
@@ -3062,7 +3062,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
}
if field.starts_with("tbl_") {
for &handle in &handles {
if let Some(acadrust::EntityType::Table(table)) =
if let Some(codec::EntityType::Table(table)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
table.block_record_handle = None;
@@ -3105,13 +3105,13 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
self.refresh_properties();
}
"material" => {
let mat_handle: Option<acadrust::Handle> = self.tabs[i]
let mat_handle: Option<codec::Handle> = self.tabs[i]
.scene
.document
.objects
.iter()
.find_map(|(h, o)| match o {
acadrust::objects::ObjectType::Material(m) if m.name == value => {
codec::objects::ObjectType::Material(m) if m.name == value => {
Some(*h)
}
_ => None,
@@ -3119,7 +3119,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
match value.as_str() {
"ByLayer" | "ByBlock" | "Global" => {
self.tabs[i].scene.document.header.current_material_handle =
acadrust::Handle::NULL;
codec::Handle::NULL;
}
_ => {
if let Some(h) = mat_handle {
@@ -3161,7 +3161,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.objects
.values()
.find_map(|object| {
let acadrust::objects::ObjectType::Layout(layout) = object
let codec::objects::ObjectType::Layout(layout) = object
else {
return None;
};
@@ -3176,7 +3176,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
if current != next {
self.push_undo_snapshot(i, "PLOTSTYLE");
for object in self.tabs[i].scene.document.objects.values_mut() {
if let acadrust::objects::ObjectType::Layout(layout) = object {
if let codec::objects::ObjectType::Layout(layout) = object {
if layout.name.eq_ignore_ascii_case(&layout_name) {
layout.plot_style_sheet = next.clone();
layout.plot_flags.plot_plot_styles = !next.is_empty();
@@ -3212,7 +3212,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
let current = active_viewport
.and_then(|handle| self.tabs[i].scene.document.get_entity(handle))
.and_then(|entity| match entity {
acadrust::EntityType::Viewport(viewport) => {
codec::EntityType::Viewport(viewport) => {
Some(viewport.ucs_icon_visible)
}
_ => None,
@@ -3235,7 +3235,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
if current != next {
self.push_undo_snapshot(i, "UCSICON");
if let Some(handle) = active_viewport {
if let Some(acadrust::EntityType::Viewport(viewport)) =
if let Some(codec::EntityType::Viewport(viewport)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
viewport.ucs_icon_visible = next;
@@ -3266,7 +3266,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
let current = active_viewport
.and_then(|handle| self.tabs[i].scene.document.get_entity(handle))
.and_then(|entity| match entity {
acadrust::EntityType::Viewport(viewport) => {
codec::EntityType::Viewport(viewport) => {
Some(viewport.status.ucs_icon_at_origin)
}
_ => None,
@@ -3289,7 +3289,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
if current != next {
self.push_undo_snapshot(i, "UCSICON");
if let Some(handle) = active_viewport {
if let Some(acadrust::EntityType::Viewport(viewport)) =
if let Some(codec::EntityType::Viewport(viewport)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
viewport.status.ucs_icon_at_origin = next;
@@ -3320,7 +3320,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
let current = active_viewport
.and_then(|handle| self.tabs[i].scene.document.get_entity(handle))
.and_then(|entity| match entity {
acadrust::EntityType::Viewport(viewport) => {
codec::EntityType::Viewport(viewport) => {
Some(viewport.ucs_per_viewport)
}
_ => None,
@@ -3343,7 +3343,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
if current != next {
self.push_undo_snapshot(i, "UCSVP");
if let Some(handle) = active_viewport {
if let Some(acadrust::EntityType::Viewport(viewport)) =
if let Some(codec::EntityType::Viewport(viewport)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
viewport.ucs_per_viewport = next;
@@ -3367,7 +3367,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
self.refresh_properties();
}
"view_visual_style" => {
use acadrust::entities::ViewportRenderMode as Mode;
use codec::entities::ViewportRenderMode as Mode;
let mode = match value.as_str() {
"2D Wireframe" | "Wireframe 2D" => Some(Mode::Wireframe2D),
"3D Wireframe" | "Wireframe 3D" => Some(Mode::Wireframe3D),
@@ -3469,7 +3469,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
"ul_width" | "ul_height" => {
let scale = handles.iter().find_map(|handle| {
match self.tabs[i].scene.document.get_entity(*handle) {
Some(acadrust::EntityType::Underlay(underlay)) => {
Some(codec::EntityType::Underlay(underlay)) => {
crate::entities::underlay::size_to_scale(
underlay,
&self.tabs[i].scene.document,
@@ -3498,17 +3498,17 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
match (field, entity) {
(
"current_fit_point",
acadrust::EntityType::Spline(spline),
codec::EntityType::Spline(spline),
) => Some(spline.fit_points.len()),
(
"current_control_point",
acadrust::EntityType::Spline(spline),
codec::EntityType::Spline(spline),
) => Some(
crate::entities::spline::control_vertex_count(spline),
),
(
"pm_current_vertex",
acadrust::EntityType::PolygonMesh(mesh),
codec::EntityType::PolygonMesh(mesh),
) => Some(mesh.vertices.len()),
_ => None,
}
@@ -3533,7 +3533,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.objects
.iter()
.find_map(|(handle, object)| match object {
acadrust::objects::ObjectType::TableStyle(style)
codec::objects::ObjectType::TableStyle(style)
if style.name.eq_ignore_ascii_case(val.trim()) =>
{
Some(*handle)
@@ -3542,7 +3542,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
});
if let Some(style_handle) = style_handle {
for &handle in &handles {
if let Some(acadrust::EntityType::Table(table)) =
if let Some(codec::EntityType::Table(table)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
table.table_style_handle = Some(style_handle);
@@ -3567,7 +3567,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
let host = self.tabs[i].scene.document.header.insertion_units;
for &handle in &handles {
let factor = match self.tabs[i].scene.document.get_entity(handle) {
Some(acadrust::EntityType::Insert(ins)) => self.tabs[i]
Some(codec::EntityType::Insert(ins)) => self.tabs[i]
.scene
.document
.block_records
@@ -3578,7 +3578,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.unwrap_or(1.0),
_ => continue,
};
if let Some(acadrust::EntityType::Insert(ins)) =
if let Some(codec::EntityType::Insert(ins)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
match axis {
@@ -3597,7 +3597,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
self.apply_block_name_commit(i, &handles, val.trim());
} else if field == "frozen_layers" {
// Resolve layer names → handles, then apply to viewports.
let layer_handles: Vec<acadrust::Handle> = val
let layer_handles: Vec<codec::Handle> = val
.split(',')
.map(|s| s.trim())
.filter(|s| !s.is_empty())
@@ -3612,7 +3612,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
})
.collect();
for &handle in &handles {
if let Some(acadrust::EntityType::Viewport(vp)) =
if let Some(codec::EntityType::Viewport(vp)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
vp.frozen_layers = layer_handles.clone();
@@ -3651,7 +3651,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
&mut self.tabs[i].scene.document,
handle,
dov::DIMTXT,
Some(acadrust::xdata::XDataValue::Real(height)),
Some(codec::xdata::XDataValue::Real(height)),
);
}
}
@@ -3659,7 +3659,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
_ if field.starts_with("dim_") => {
if matches!(
self.tabs[i].scene.document.get_entity(handle),
Some(acadrust::EntityType::Dimension(_))
Some(codec::EntityType::Dimension(_))
) {
let applied = crate::entities::dim_override::set_property(
&mut self.tabs[i].scene.document,
@@ -3668,8 +3668,8 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
&val,
);
if applied && field == "dim_text_inside" {
if let Some(acadrust::EntityType::Dimension(
acadrust::entities::Dimension::LargeRadial(
if let Some(codec::EntityType::Dimension(
codec::entities::Dimension::LargeRadial(
dimension,
),
)) = self.tabs[i]
@@ -3688,7 +3688,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
let vals = if val.trim().is_empty() {
None
} else {
Some(vec![acadrust::xdata::XDataValue::String(
Some(vec![codec::xdata::XDataValue::String(
val.clone(),
)])
};
@@ -3724,7 +3724,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
&mut self.tabs[i].scene.document,
handle,
code,
Some(acadrust::xdata::XDataValue::Real(n)),
Some(codec::xdata::XDataValue::Real(n)),
);
}
}
@@ -3767,7 +3767,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.document
.get_entity(handle)
.and_then(|entity| match entity {
acadrust::EntityType::MLine(mline) => {
codec::EntityType::MLine(mline) => {
crate::entities::mline::resolved_mline_style(
mline,
&self.tabs[i].scene.document,
@@ -3796,7 +3796,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
);
if field == "ml_scale" {
if let (
acadrust::EntityType::MLine(mline),
codec::EntityType::MLine(mline),
Some(style),
) = (entity, mline_style.as_ref())
{
@@ -3817,7 +3817,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
}
if field.starts_with("tbl_") {
for &handle in &handles {
if let Some(acadrust::EntityType::Table(table)) =
if let Some(codec::EntityType::Table(table)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
table.block_record_handle = None;
@@ -3866,7 +3866,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
/// the definition the (single-block) selection references is renamed and
/// every insert of it follows. Anonymous/xref definitions never get here —
/// their Name row stays read-only.
fn apply_block_name_commit(&mut self, i: usize, handles: &[acadrust::Handle], new: &str) {
fn apply_block_name_commit(&mut self, i: usize, handles: &[codec::Handle], new: &str) {
if new.is_empty() {
return;
}
@@ -3887,7 +3887,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
if self.tabs[i].scene.is_layer_locked(handle) {
continue;
}
if let Some(acadrust::EntityType::Insert(ins)) =
if let Some(codec::EntityType::Insert(ins)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
if ins.block_name != canon {
@@ -3905,7 +3905,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// same definition; a mixed selection makes the rename target ambiguous.
let mut old: Option<String> = None;
for &handle in handles {
if let Some(acadrust::EntityType::Insert(ins)) =
if let Some(codec::EntityType::Insert(ins)) =
self.tabs[i].scene.document.get_entity(handle)
{
match &old {
@@ -3938,7 +3938,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
};
self.push_undo_snapshot(i, "ATTEDIT");
for &handle in &handles {
if let Some(acadrust::EntityType::Insert(ins)) =
if let Some(codec::EntityType::Insert(ins)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
if let Some(attr) = ins.attributes.iter_mut().find(|a| a.tag == tag) {
@@ -3955,7 +3955,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
/// Open the attribute editor dialog for the given INSERT, loading a working
/// copy of its attribute values. No-op (with a hint) when the block has no
/// attributes. Entry points: double-clicking such a block, or ATTEDIT.
pub(crate) fn open_attribute_editor(&mut self, handle: acadrust::Handle) {
pub(crate) fn open_attribute_editor(&mut self, handle: codec::Handle) {
let i = self.active_tab;
if self.reject_locked_edit(i, handle) {
return;
@@ -3964,7 +3964,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
// Ok((block, rows)) to open; Err(msg) to report and stay closed. The
// borrow of `doc` ends with this match, before any `self` mutation.
let result = match doc.get_entity(handle) {
Some(acadrust::EntityType::Insert(ins)) if !ins.attributes.is_empty() => {
Some(codec::EntityType::Insert(ins)) if !ins.attributes.is_empty() => {
// The prompt text lives on the block's ATTDEFs, not on the
// attribute instances — map tag → prompt from the definition.
let prompts = block_attr_prompts(doc, &ins.block_name);
@@ -3975,7 +3975,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
.collect::<Vec<_>>();
Ok((ins.block_name.clone(), rows))
}
Some(acadrust::EntityType::Insert(_)) => {
Some(codec::EntityType::Insert(_)) => {
Err("ATTEDIT This block has no attributes.")
}
_ => Err("ATTEDIT Select a block with attributes."),
@@ -4043,7 +4043,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
self.push_undo_snapshot(i, "ATTEDIT");
let mut changed = false;
if let Some(acadrust::EntityType::Insert(ins)) =
if let Some(codec::EntityType::Insert(ins)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
if ins.block_name == block && rows.len() == ins.attributes.len() {
@@ -4067,7 +4067,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
/// Build the editor's working copy of one attribute. Angles are shown in
/// degrees; numeric fields become strings so the user can type freely.
fn attr_row_from_entity(
a: &acadrust::entities::AttributeEntity,
a: &codec::entities::AttributeEntity,
prompts: &rustc_hash::FxHashMap<String, String>,
) -> AttrRow {
let fmt = |v: f64| format!("{v}");
@@ -4094,7 +4094,7 @@ fn attr_row_from_entity(
/// Write one edited row back onto its attribute; returns whether anything
/// changed. Numeric fields are parsed (angles from degrees); an unparseable
/// field is left as-is.
fn apply_attr_row(a: &mut acadrust::entities::AttributeEntity, row: &AttrRow) -> bool {
fn apply_attr_row(a: &mut codec::entities::AttributeEntity, row: &AttrRow) -> bool {
let mut ch = false;
if a.get_value() != row.value {
a.set_value(row.value.clone());
@@ -4171,13 +4171,13 @@ fn apply_attr_row(a: &mut acadrust::entities::AttributeEntity, row: &AttrRow) ->
/// ATTDEF. Attribute instances (ATTRIB) carry only tag + value; the prompt is
/// defined once on the block definition. Tags with no definition are absent.
fn block_attr_prompts(
doc: &acadrust::CadDocument,
doc: &codec::CadDocument,
block_name: &str,
) -> rustc_hash::FxHashMap<String, String> {
let mut map = rustc_hash::FxHashMap::default();
if let Some(br) = doc.block_records.get(block_name) {
for &eh in &br.entity_handles {
if let Some(acadrust::EntityType::AttributeDefinition(ad)) = doc.get_entity(eh) {
if let Some(codec::EntityType::AttributeDefinition(ad)) = doc.get_entity(eh) {
map.insert(ad.tag.clone(), ad.prompt.clone());
}
}
@@ -4188,8 +4188,8 @@ fn block_attr_prompts(
#[cfg(test)]
mod layer_rename_tests {
use crate::app::OpenCADStudio;
use acadrust::entities::Line;
use acadrust::{EntityType, Handle};
use codec::entities::Line;
use codec::{EntityType, Handle};
fn app_with_editing_layer() -> OpenCADStudio {
let mut app = OpenCADStudio::new_for_test();
+15 -15
View File
@@ -11,7 +11,7 @@ use crate::ui::popup::context_menu::{
build_context_menu, ContextMenu, GripMenuCmd, GripMenuContext, MenuAction, MenuContext,
SubmenuId,
};
use acadrust::Handle;
use codec::Handle;
use iced::Task;
impl OpenCADStudio {
@@ -522,7 +522,7 @@ mod tests {
.scene
.document
.entities()
.filter(|e| matches!(e, acadrust::EntityType::Line(_)))
.filter(|e| matches!(e, codec::EntityType::Line(_)))
.count();
assert_eq!(lines, 3, "{mode:?}");
}
@@ -540,7 +540,7 @@ mod tests {
assert!(!menu_open(&app));
assert_eq!(active(&app), None);
let closed = app.tabs[0].scene.document.entities().any(|e| {
matches!(e, acadrust::EntityType::LwPolyline(p) if p.is_closed && p.vertices.len() == 3)
matches!(e, codec::EntityType::LwPolyline(p) if p.is_closed && p.vertices.len() == 3)
});
assert!(closed, "PLINE should have been closed by the menu pick");
});
@@ -602,7 +602,7 @@ mod tests {
assert!(!menu_open(&app));
assert_eq!(active(&app), None);
let closed = app.tabs[0].scene.document.entities().any(
|e| matches!(e, acadrust::EntityType::LwPolyline(p) if p.is_closed),
|e| matches!(e, codec::EntityType::LwPolyline(p) if p.is_closed),
);
assert!(closed);
});
@@ -641,7 +641,7 @@ mod tests {
.scene
.document
.entities()
.filter(|e| matches!(e, acadrust::EntityType::Line(_)))
.filter(|e| matches!(e, codec::EntityType::Line(_)))
.count();
assert_eq!(lines, 3);
});
@@ -658,7 +658,7 @@ mod tests {
.document
.entities()
.find_map(|e| match e {
acadrust::EntityType::Line(l) => Some(l.common.handle),
codec::EntityType::Line(l) => Some(l.common.handle),
_ => None,
})
.expect("a line");
@@ -673,7 +673,7 @@ mod tests {
.scene
.document
.entities()
.filter(|e| matches!(e, acadrust::EntityType::Line(_)))
.filter(|e| matches!(e, codec::EntityType::Line(_)))
.count();
assert_eq!(lines, 0);
});
@@ -683,7 +683,7 @@ mod tests {
/// A drawing with one line, selected, its start grip hot at the origin.
fn grip_app() -> (OpenCADStudio, Handle) {
use acadrust::{entities::Line, types::Vector3, EntityType};
use codec::{entities::Line, types::Vector3, EntityType};
let mut app = app();
app.snapper.snap_enabled = false;
app.snapper.grid_snap_on = false;
@@ -717,7 +717,7 @@ mod tests {
fn line_start(app: &OpenCADStudio, handle: Handle) -> (f64, f64) {
match app.tabs[0].scene.document.get_entity(handle) {
Some(acadrust::EntityType::Line(l)) => (l.start.x, l.start.y),
Some(codec::EntityType::Line(l)) => (l.start.x, l.start.y),
other => panic!("{other:?}"),
}
}
@@ -795,7 +795,7 @@ mod tests {
.document
.entities()
.filter_map(|e| match e {
acadrust::EntityType::Line(l) => Some((l.start.x, l.start.y)),
codec::EntityType::Line(l) => Some((l.start.x, l.start.y)),
_ => None,
})
.collect();
@@ -810,7 +810,7 @@ mod tests {
.scene
.document
.entities()
.filter(|e| matches!(e, acadrust::EntityType::Line(_)))
.filter(|e| matches!(e, codec::EntityType::Line(_)))
.count();
assert_eq!(count, 1);
});
@@ -895,7 +895,7 @@ mod transparent_tests {
.scene
.document
.entities()
.filter(|e| matches!(e, acadrust::EntityType::Line(_)))
.filter(|e| matches!(e, codec::EntityType::Line(_)))
.count();
assert_eq!(lines, 1);
});
@@ -961,7 +961,7 @@ mod transparent_tests {
.document
.entities()
.filter_map(|e| match e {
acadrust::EntityType::Line(l) => Some(l.clone()),
codec::EntityType::Line(l) => Some(l.clone()),
_ => None,
})
.collect();
@@ -984,7 +984,7 @@ mod transparent_tests {
.document
.entities()
.filter_map(|e| match e {
acadrust::EntityType::Line(l) => Some(l.clone()),
codec::EntityType::Line(l) => Some(l.clone()),
_ => None,
})
.collect();
@@ -1000,7 +1000,7 @@ mod transparent_tests {
.document
.entities()
.filter_map(|e| match e {
acadrust::EntityType::Line(l) => Some(l.clone()),
codec::EntityType::Line(l) => Some(l.clone()),
_ => None,
})
.collect();
+48 -48
View File
@@ -16,8 +16,8 @@ use crate::scene::{
self, hover_id, CubeRegion, Scene, VIEWCUBE_DRAW_PX, VIEWCUBE_PAD, VIEWCUBE_PX,
};
use crate::ui::PropertiesPanel;
use acadrust::types::Color as AcadColor;
use acadrust::{EntityType as AcadEntityType, Handle};
use codec::types::Color as AcadColor;
use codec::{EntityType as AcadEntityType, Handle};
use iced::time::Instant;
use iced::{mouse, Point, Task};
@@ -364,7 +364,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
/// model-space entities (base = the file's model-space insertion base).
fn import_document_as_block(
&mut self,
doc: acadrust::CadDocument,
doc: codec::CadDocument,
stem: String,
) -> Result<String, String> {
let i = self.active_tab;
@@ -373,15 +373,15 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
.objects
.values()
.find_map(|o| {
if let acadrust::objects::ObjectType::Layout(l) = o {
if let codec::objects::ObjectType::Layout(l) = o {
(l.name == "Model" && !l.block_record.is_null()).then_some(l.block_record)
} else {
None
}
})
.or_else(|| doc.block_records.get("*Model_Space").map(|br| br.handle))
.unwrap_or(acadrust::Handle::NULL);
let mut entities: Vec<acadrust::EntityType> = if model_br.is_null() {
.unwrap_or(codec::Handle::NULL);
let mut entities: Vec<codec::EntityType> = if model_br.is_null() {
Vec::new()
} else {
let br = doc.block_records.iter().find(|br| br.handle == model_br);
@@ -392,7 +392,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
.iter()
.filter_map(|h| doc.get_entity(*h))
.filter(|e| {
!matches!(e, acadrust::EntityType::Block(_) | acadrust::EntityType::BlockEnd(_))
!matches!(e, codec::EntityType::Block(_) | codec::EntityType::BlockEnd(_))
})
.cloned()
.collect()
@@ -405,7 +405,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
o == model_br || o.is_null()
})
.filter(|e| {
!matches!(e, acadrust::EntityType::Block(_) | acadrust::EntityType::BlockEnd(_))
!matches!(e, codec::EntityType::Block(_) | codec::EntityType::BlockEnd(_))
})
.cloned()
.collect()
@@ -472,7 +472,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
.iter_mut()
.chain(defs.iter_mut().flat_map(|def| def.entities.iter_mut()))
{
if let acadrust::EntityType::Insert(ins) = entity {
if let codec::EntityType::Insert(ins) = entity {
if let Some(new_name) = rename_map.get(&ins.block_name) {
ins.block_name = new_name.clone();
}
@@ -852,18 +852,18 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
// not persist an unloaded bit), so keep their source entities but
// remove their decoded render models. A reload repopulates the cache
// after clearing the corresponding session key.
let hidden_images: Vec<acadrust::types::Handle> = self.tabs[i]
let hidden_images: Vec<codec::types::Handle> = self.tabs[i]
.scene
.document
.entities()
.filter_map(|entity| match entity {
acadrust::EntityType::RasterImage(image)
codec::EntityType::RasterImage(image)
if image.definition_handle.is_some_and(|key| self.tabs[i].xref_unloaded.is_unloaded(key.value())) =>
{
Some(entity.common().handle)
}
acadrust::EntityType::Underlay(underlay)
if matches!(underlay.underlay_type, acadrust::entities::UnderlayType::Pdf)
codec::EntityType::Underlay(underlay)
if matches!(underlay.underlay_type, codec::entities::UnderlayType::Pdf)
&& self.tabs[i].xref_unloaded.is_unloaded(underlay.definition_handle.value()) =>
{
Some(entity.common().handle)
@@ -1023,8 +1023,8 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
if row_kind != kind || row_name != name {
continue;
}
let handle = acadrust::types::Handle::new(*key);
if let Some(acadrust::objects::ObjectType::UnderlayDefinition(def)) =
let handle = codec::types::Handle::new(*key);
if let Some(codec::objects::ObjectType::UnderlayDefinition(def)) =
self.tabs[i].scene.document.objects.get_mut(&handle)
{
def.unloaded = false;
@@ -1043,7 +1043,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
self.tabs[i].xref_unloaded.remove(key);
self.tabs[i].xref_stat_cache.remove(key);
}
let handles: rustc_hash::FxHashSet<acadrust::types::Handle> = self.tabs[i]
let handles: rustc_hash::FxHashSet<codec::types::Handle> = self.tabs[i]
.scene
.document
.block_records
@@ -1282,9 +1282,9 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
mod tests {
use super::*;
use crate::app::OpenCADStudio;
use acadrust::entities::Line;
use acadrust::types::Vector3;
use acadrust::EntityType;
use codec::entities::Line;
use codec::types::Vector3;
use codec::EntityType;
fn fresh() -> OpenCADStudio {
let mut app = OpenCADStudio::new_for_test();
@@ -1293,13 +1293,13 @@ mod tests {
}
/// A foreign document: the fresh scene's document plus one model-space LINE.
fn foreign_doc(app: &OpenCADStudio) -> acadrust::CadDocument {
fn foreign_doc(app: &OpenCADStudio) -> codec::CadDocument {
let mut doc = app.tabs[app.active_tab].scene.document.clone();
let model_br = doc
.objects
.values()
.find_map(|o| {
if let acadrust::objects::ObjectType::Layout(l) = o {
if let codec::objects::ObjectType::Layout(l) = o {
(l.name == "Model" && !l.block_record.is_null()).then_some(l.block_record)
} else {
None
@@ -1331,7 +1331,7 @@ mod tests {
#[test]
fn import_document_as_block_merges_source_only_layer() {
use acadrust::tables::Layer;
use codec::tables::Layer;
let mut app = fresh();
let mut doc = foreign_doc(&app);
@@ -1342,7 +1342,7 @@ mod tests {
.objects
.values()
.find_map(|o| match o {
acadrust::objects::ObjectType::Layout(l) if l.name == "Model" => {
codec::objects::ObjectType::Layout(l) if l.name == "Model" => {
Some(l.block_record)
}
_ => None,
@@ -1367,10 +1367,10 @@ mod tests {
/// definition itself INSERTs a `Door` block — so the imported `Door` is a
/// *nested dependency*, not a top-level entity. The `Door` in this file is
/// unrelated to any `Door` in the destination drawing.
fn nested_foreign_doc(app: &OpenCADStudio) -> acadrust::CadDocument {
use acadrust::entities::Insert;
use acadrust::tables::BlockRecord;
use acadrust::Handle;
fn nested_foreign_doc(app: &OpenCADStudio) -> codec::CadDocument {
use codec::entities::Insert;
use codec::tables::BlockRecord;
use codec::Handle;
let mut doc = foreign_doc(app);
// "Door" block definition: one LINE of geometry.
@@ -1398,7 +1398,7 @@ mod tests {
.objects
.values()
.find_map(|o| {
if let acadrust::objects::ObjectType::Layout(l) = o {
if let codec::objects::ObjectType::Layout(l) = o {
(l.name == "Model" && !l.block_record.is_null()).then_some(l.block_record)
} else {
None
@@ -1415,7 +1415,7 @@ mod tests {
/// The nested-INSERT's block name inside a defined block record.
fn nested_insert_target(
doc: &acadrust::CadDocument,
doc: &codec::CadDocument,
block: &str,
) -> Option<String> {
let br = doc.block_records.get(block)?;
@@ -1428,10 +1428,10 @@ mod tests {
/// A foreign document whose model space INSERTs a `Fixture` block whose
/// definition INSERTs `Door (2)`, whose definition in turn INSERTs `Door`.
/// The file therefore carries *both* `Door` and `Door (2)` as nested deps.
fn doubly_nested_foreign_doc(app: &OpenCADStudio) -> acadrust::CadDocument {
use acadrust::entities::Insert;
use acadrust::tables::BlockRecord;
use acadrust::Handle;
fn doubly_nested_foreign_doc(app: &OpenCADStudio) -> codec::CadDocument {
use codec::entities::Insert;
use codec::tables::BlockRecord;
use codec::Handle;
let mut doc = foreign_doc(app);
let door_h = Handle::new(doc.next_handle());
@@ -1464,7 +1464,7 @@ mod tests {
.objects
.values()
.find_map(|o| {
if let acadrust::objects::ObjectType::Layout(l) = o {
if let codec::objects::ObjectType::Layout(l) = o {
(l.name == "Model" && !l.block_record.is_null()).then_some(l.block_record)
} else {
None
@@ -1588,7 +1588,7 @@ mod tests {
#[test]
fn blockpalette_reflects_new_block_without_reopen() {
use acadrust::types::Transform;
use codec::types::Transform;
let mut app = fresh();
let i = app.active_tab;
@@ -1793,7 +1793,7 @@ mod tests {
let new_dir = dir.join("new");
std::fs::create_dir_all(&old_dir).unwrap();
std::fs::create_dir_all(&new_dir).unwrap();
let mut br = acadrust::tables::BlockRecord::new("PLAN");
let mut br = codec::tables::BlockRecord::new("PLAN");
br.flags.is_xref = true;
br.xref_path = "refs/plan.dwg".to_string();
br.handle = app.tabs[i].scene.document.allocate_handle();
@@ -1863,11 +1863,11 @@ mod tests {
// Behavioral matrix: every row op on a NESTED row via the GUI
// message path. Nested rows must report per-entry errors (CLI
// wording), never silently skip.
use acadrust::tables::BlockRecord;
use codec::tables::BlockRecord;
use crate::app::Message;
use crate::ui::window::xref_manager::XrefPaletteOp;
let dir = palette_tmpdir("nestedmatrix");
let mut host_doc = acadrust::CadDocument::new();
let mut host_doc = codec::CadDocument::new();
let mut inner = BlockRecord::new("INNER");
inner.flags.is_xref = true;
inner.xref_path = "inner.dwg".to_string();
@@ -1908,7 +1908,7 @@ mod tests {
fn palette_detach_unload_rowop_gui_path() {
// Reproduction for "Detach/Unload from the palette do nothing":
// drive the exact GUI message path (row right-click menu item).
use acadrust::tables::BlockRecord;
use codec::tables::BlockRecord;
use crate::app::Message;
use crate::ui::window::xref_manager::XrefPaletteOp;
let mut app = fresh();
@@ -1943,7 +1943,7 @@ mod tests {
fn palette_overlay_and_pathtype_rowop_gui_path() {
// Row-menu Overlay + Change-Path row ops on a direct row via the
// GUI message path: type flag flips, saved path clears.
use acadrust::tables::BlockRecord;
use codec::tables::BlockRecord;
use crate::app::Message;
use crate::io::xref_model::{Pathtype, RefType};
use crate::ui::window::xref_manager::XrefPaletteOp;
@@ -1976,9 +1976,9 @@ mod tests {
fn palette_reload_all_resolves_direct_refs() {
// Toolbar Reload All against a real on-disk reference: full
// resolve, per-ref report, entry back to Loaded.
use acadrust::tables::BlockRecord;
use codec::tables::BlockRecord;
let dir = palette_tmpdir("reloadall");
let ref_doc = acadrust::CadDocument::new();
let ref_doc = codec::CadDocument::new();
let bytes = crate::io::save_to_bytes(&ref_doc, "dwg", ref_doc.version).unwrap();
std::fs::write(dir.join("plan.dwg"), &bytes).unwrap();
let mut app = fresh();
@@ -2012,10 +2012,10 @@ mod tests {
fn palette_unload_nested_reports_per_entry() {
// F6: palette Unload on a nested row reports the per-entry nested
// error (CLI wording) instead of the confusing 'no loaded reference'.
use acadrust::tables::BlockRecord;
use codec::tables::BlockRecord;
use crate::ui::window::xref_manager::XrefPaletteOp;
let dir = palette_tmpdir("nested");
let mut host_doc = acadrust::CadDocument::new();
let mut host_doc = codec::CadDocument::new();
let mut inner = BlockRecord::new("INNER");
inner.flags.is_xref = true;
inner.xref_path = "inner.dwg".to_string();
@@ -2047,7 +2047,7 @@ mod tests {
// F7: palette Reload on an image/PDF row reports the drawing-only
// error and leaves its unloaded flag untouched (no spurious
// no-match after a flag clear).
use acadrust::objects::{ImageDefinition, ObjectType};
use codec::objects::{ImageDefinition, ObjectType};
use crate::io::xref_model::RefKind;
use crate::ui::window::xref_manager::XrefPaletteOp;
let dir = palette_tmpdir("imgreload");
@@ -2057,14 +2057,14 @@ mod tests {
let mut def = ImageDefinition::with_dimensions("img.png", 8, 8);
def.handle = h;
app.tabs[i].scene.document.objects.insert(h, ObjectType::ImageDefinition(def));
let mut img = acadrust::entities::RasterImage::new(
let mut img = codec::entities::RasterImage::new(
"img.png",
acadrust::types::Vector3::ZERO,
codec::types::Vector3::ZERO,
8.0,
8.0,
);
img.definition_handle = Some(h);
app.tabs[i].scene.document.add_entity(acadrust::EntityType::RasterImage(img)).unwrap();
app.tabs[i].scene.document.add_entity(codec::EntityType::RasterImage(img)).unwrap();
app.tabs[i].current_path = Some(dir.join("host.dwg"));
app.refresh_xref_manager();
let idx = app.xref_manager.entries.iter().position(|e| e.kind == RefKind::Image).expect("image listed");
+3 -3
View File
@@ -15,8 +15,8 @@ use crate::scene::{
self, hover_id, CubeRegion, Scene, VIEWCUBE_DRAW_PX, VIEWCUBE_PAD, VIEWCUBE_PX,
};
use crate::ui::PropertiesPanel;
use acadrust::types::Color as AcadColor;
use acadrust::{EntityType as AcadEntityType, Handle};
use codec::types::Color as AcadColor;
use codec::{EntityType as AcadEntityType, Handle};
use iced::time::Instant;
use iced::{mouse, Point, Task};
@@ -330,7 +330,7 @@ impl OpenCADStudio {
/// following `ARC_CONT` starts tangentially from where drawing ended. Set to
/// `None` for any other entity kind. Uses `last_point` (the final pick) to
/// pick the endpoint the pen actually finished on.
pub(in crate::app) fn update_cont_anchor(&mut self, entity: &acadrust::EntityType) {
pub(in crate::app) fn update_cont_anchor(&mut self, entity: &codec::EntityType) {
let last = self.last_point;
self.cont_anchor = crate::modules::draw::draw::arc::continue_anchor(entity, last);
}
+82 -82
View File
@@ -14,8 +14,8 @@ use crate::scene::{
self, hover_id, CubeRegion, Scene, VIEWCUBE_DRAW_PX, VIEWCUBE_PAD, VIEWCUBE_PX,
};
use crate::ui::PropertiesPanel;
use acadrust::types::Color as AcadColor;
use acadrust::{EntityType as AcadEntityType, Handle};
use codec::types::Color as AcadColor;
use codec::{EntityType as AcadEntityType, Handle};
use iced::time::Instant;
use iced::{mouse, Point, Task};
@@ -64,8 +64,8 @@ fn scale_name_for_factor(scales: &[(String, f64)], factor: f64) -> Option<String
fn plot_render_mode_override(
d: &crate::ui::window::plot::PlotDialogState,
) -> Option<acadrust::entities::ViewportRenderMode> {
use acadrust::entities::ViewportRenderMode as Mode;
) -> Option<codec::entities::ViewportRenderMode> {
use codec::entities::ViewportRenderMode as Mode;
match d.shade.as_str() {
"2D Wireframe" => Some(Mode::Wireframe2D),
"3D Wireframe" => Some(Mode::Wireframe3D),
@@ -123,7 +123,7 @@ fn plot_dialog_sheet_mm(d: &crate::ui::window::plot::PlotDialogState) -> (f64, f
/// Whether the dialog still names the sheet the stored settings carry.
fn paper_unchanged(
d: &crate::ui::window::plot::PlotDialogState,
stored: &acadrust::objects::PlotSettings,
stored: &codec::objects::PlotSettings,
) -> bool {
!stored.paper_size.is_empty()
&& crate::io::paper_catalog::from_drawing(
@@ -143,7 +143,7 @@ fn paper_unchanged(
/// selection writes the canonical name.
fn paper_name_for_settings(
d: &crate::ui::window::plot::PlotDialogState,
stored: &acadrust::objects::PlotSettings,
stored: &codec::objects::PlotSettings,
) -> String {
if paper_unchanged(d, stored) {
stored.paper_size.clone()
@@ -161,8 +161,8 @@ fn paper_name_for_settings(
fn plot_dialog_rotation(
d: &crate::ui::window::plot::PlotDialogState,
natural: crate::io::paper_catalog::Orientation,
) -> acadrust::objects::PlotRotation {
use acadrust::objects::PlotRotation;
) -> codec::objects::PlotRotation {
use codec::objects::PlotRotation;
match (plot_dialog_orientation(d) != natural, d.upside_down) {
(false, false) => PlotRotation::None,
(true, false) => PlotRotation::Degrees90,
@@ -172,9 +172,9 @@ fn plot_dialog_rotation(
}
/// Millimetres in the paper unit a page setup counts in.
fn plot_paper_unit_mm(units: acadrust::objects::PlotPaperUnits) -> f64 {
fn plot_paper_unit_mm(units: codec::objects::PlotPaperUnits) -> f64 {
match units {
acadrust::objects::PlotPaperUnits::Inches => 25.4,
codec::objects::PlotPaperUnits::Inches => 25.4,
_ => 1.0,
}
}
@@ -183,16 +183,16 @@ fn plot_paper_unit_mm(units: acadrust::objects::PlotPaperUnits) -> f64 {
/// is the `paper : drawing` ratio times 25.4 on millimetre page setups and
/// the plain ratio on inch ones — observed in its files, whatever the
/// published description says. Both directions of that convention live here.
fn stored_scale_factor(ratio: f64, units: acadrust::objects::PlotPaperUnits) -> f64 {
fn stored_scale_factor(ratio: f64, units: codec::objects::PlotPaperUnits) -> f64 {
match units {
acadrust::objects::PlotPaperUnits::Millimeters => ratio * 25.4,
codec::objects::PlotPaperUnits::Millimeters => ratio * 25.4,
_ => ratio,
}
}
fn ratio_from_stored_scale_factor(factor: f64, units: acadrust::objects::PlotPaperUnits) -> f64 {
fn ratio_from_stored_scale_factor(factor: f64, units: codec::objects::PlotPaperUnits) -> f64 {
match units {
acadrust::objects::PlotPaperUnits::Millimeters => factor / 25.4,
codec::objects::PlotPaperUnits::Millimeters => factor / 25.4,
_ => factor,
}
}
@@ -200,8 +200,8 @@ fn ratio_from_stored_scale_factor(factor: f64, units: acadrust::objects::PlotPap
/// The file format's standard scale for a `paper : drawing` ratio, when it
/// has one. Only the metric ratios exist as standard codes here; an
/// architectural scale is stored as a custom ratio with the same value.
fn standard_scale_for_ratio(paper: f64, drawing: f64) -> Option<acadrust::objects::ScaledType> {
use acadrust::objects::ScaledType as S;
fn standard_scale_for_ratio(paper: f64, drawing: f64) -> Option<codec::objects::ScaledType> {
use codec::objects::ScaledType as S;
const STANDARD: &[(f64, f64, S)] = &[
(1.0, 1.0, S::OneToOne),
(1.0, 2.0, S::OneToTwo),
@@ -267,7 +267,7 @@ fn plot_dialog_device(d: &crate::ui::window::plot::PlotDialogState) -> crate::io
/// device, or one of our own legacy labels, is written in the source application's spelling.
fn device_name_for_settings(
d: &crate::ui::window::plot::PlotDialogState,
stored: &acadrust::objects::PlotSettings,
stored: &codec::objects::PlotSettings,
) -> String {
use crate::io::plot_device::PlotDevice;
let device = plot_dialog_device(d);
@@ -285,8 +285,8 @@ fn device_name_for_settings(
/// the equivalent of the source application's `PAPERUPDATE`.
fn margins_for_settings(
d: &crate::ui::window::plot::PlotDialogState,
stored: &acadrust::objects::PlotSettings,
) -> acadrust::objects::PaperMargin {
stored: &codec::objects::PlotSettings,
) -> codec::objects::PaperMargin {
use crate::io::plot_device::PlotDevice;
let device = plot_dialog_device(d);
let (stored_device, _) = PlotDevice::from_stored_name(&stored.printer_name);
@@ -294,7 +294,7 @@ fn margins_for_settings(
return stored.margins;
}
let margins = device.margins_mm(&plot_dialog_paper(d), &d.custom_papers);
acadrust::objects::PaperMargin::new(margins.left, margins.bottom, margins.right, margins.top)
codec::objects::PaperMargin::new(margins.left, margins.bottom, margins.right, margins.top)
}
fn plot_content_extents(content: &PlotContent) -> Option<(f64, f64, f64, f64)> {
@@ -372,13 +372,13 @@ fn plot_owner_aci(scene: &crate::scene::Scene, wire: &mut crate::scene::WireMode
};
let common = entity.common();
wire.aci = match &common.color {
acadrust::types::Color::Index(index) => *index,
acadrust::types::Color::ByLayer => scene
codec::types::Color::Index(index) => *index,
codec::types::Color::ByLayer => scene
.document
.layers
.get(&common.layer)
.map(|layer| match &layer.color {
acadrust::types::Color::Index(index) => *index,
codec::types::Color::Index(index) => *index,
_ => 0,
})
.unwrap_or(7),
@@ -389,7 +389,7 @@ fn plot_owner_aci(scene: &crate::scene::Scene, wire: &mut crate::scene::WireMode
fn plot_scene_content(
scene: &crate::scene::Scene,
paper_space_last: bool,
render_mode_override: Option<acadrust::entities::ViewportRenderMode>,
render_mode_override: Option<codec::entities::ViewportRenderMode>,
) -> PlotContent {
let (mut paper_wires, mut model_wires) = scene.plot_wire_groups(render_mode_override);
let plot_viewport_borders = scene
@@ -403,7 +403,7 @@ fn plot_scene_content(
.is_some_and(|entity| {
matches!(
entity,
acadrust::EntityType::Viewport(viewport)
codec::EntityType::Viewport(viewport)
if !crate::scene::Scene::is_sheet_viewport(
&scene.document,
viewport,
@@ -495,9 +495,9 @@ fn plot_scene_content(
impl OpenCADStudio {
/// Persist exact ACIS bodies and kernel-derived edge caches before saving.
fn sync_solid_models_for_save(&mut self, i: usize) {
use acadrust::EntityType;
use codec::EntityType;
let scene = &mut self.tabs[i].scene;
let targets: Vec<(acadrust::Handle, bool, bool)> = scene
let targets: Vec<(codec::Handle, bool, bool)> = scene
.document
.entities()
.filter_map(|entity| {
@@ -536,13 +536,13 @@ impl OpenCADStudio {
.get(index * 2 + 1)
.copied()
.unwrap_or([0.0; 3]);
acadrust::entities::Wire::from_points(vec![
acadrust::types::Vector3::new(
codec::entities::Wire::from_points(vec![
codec::types::Vector3::new(
points[0][0] as f64 + first_low[0] as f64,
points[0][1] as f64 + first_low[1] as f64,
points[0][2] as f64 + first_low[2] as f64,
),
acadrust::types::Vector3::new(
codec::types::Vector3::new(
points[1][0] as f64 + second_low[0] as f64,
points[1][1] as f64 + second_low[1] as f64,
points[1][2] as f64 + second_low[2] as f64,
@@ -565,7 +565,7 @@ impl OpenCADStudio {
/// Write a header variable on the active drawing and mark it modified.
pub(in crate::app) fn set_drawing_var(
&mut self,
write: impl FnOnce(&mut acadrust::document::HeaderVariables),
write: impl FnOnce(&mut codec::document::HeaderVariables),
) {
let i = self.active_tab;
if let Some(tab) = self.tabs.get_mut(i) {
@@ -1459,7 +1459,7 @@ impl OpenCADStudio {
&mut self,
i: usize,
path: std::path::PathBuf,
version: acadrust::DxfVersion,
version: codec::DxfVersion,
set_current_path: bool,
) -> Result<(), crate::io::SaveFailure> {
let previous_autosave = self.autosave_target(i);
@@ -1591,7 +1591,7 @@ impl OpenCADStudio {
&mut self,
name: String,
path: std::path::PathBuf,
doc: acadrust::CadDocument,
doc: codec::CadDocument,
mut caches: crate::scene::DerivedCaches,
) -> Task<Message> {
// If the user clicked Cancel while the parser was running, the
@@ -1612,7 +1612,7 @@ impl OpenCADStudio {
}) || doc
.notifications
.iter()
.any(|item| item.notification_type == acadrust::notification::NotificationType::Error);
.any(|item| item.notification_type == codec::notification::NotificationType::Error);
let reference_recovered = caches
.xrefs
.iter()
@@ -2142,7 +2142,7 @@ impl OpenCADStudio {
tab_id: u64,
filename: String,
ext: String,
version: acadrust::DxfVersion,
version: codec::DxfVersion,
bounds: Option<iced::Rectangle>,
screenshot: Option<iced::window::Screenshot>,
) -> Task<Message> {
@@ -2155,7 +2155,7 @@ impl OpenCADStudio {
crate::io::thumbnail::from_screenshot(
screenshot,
bounds,
version >= acadrust::DxfVersion::AC1027,
version >= codec::DxfVersion::AC1027,
)
})
});
@@ -2215,7 +2215,7 @@ impl OpenCADStudio {
&mut self,
i: usize,
path: std::path::PathBuf,
version: acadrust::DxfVersion,
version: codec::DxfVersion,
purpose: crate::app::SavePurpose,
continuation: crate::app::SaveContinuation,
set_current_path: bool,
@@ -2357,7 +2357,7 @@ impl OpenCADStudio {
let revision = self.tabs[i].edit_revision;
let camera_generation = self.tabs[i].scene.camera_generation;
let thumbnail = (purpose != crate::app::SavePurpose::Autosave && i == self.active_tab)
.then_some(version >= acadrust::DxfVersion::AC1027);
.then_some(version >= codec::DxfVersion::AC1027);
let capture_bounds = thumbnail.and_then(|_| {
crate::ui::wrap_bar::dropdown_bounds(crate::app::view::VIEWPORT_CAPTURE_BOUNDS_ID)
});
@@ -3216,7 +3216,7 @@ impl OpenCADStudio {
/// paper-unit conversion, the way the commercial application writes
/// "1:1" on an inch page setup over a millimetre paper space as
/// `1 in = 25.4 units`.
fn dialog_plot_scale_ratio(&self) -> ((f64, f64), Option<acadrust::objects::ScaledType>) {
fn dialog_plot_scale_ratio(&self) -> ((f64, f64), Option<codec::objects::ScaledType>) {
let d = &self.plot_dialog;
let scene = &self.tabs[self.active_tab].scene;
let factor = plot_dialog_scale_factor(d);
@@ -3347,8 +3347,8 @@ impl OpenCADStudio {
/// Everything the dialog has no control for (viewport-border and
/// paper-update flags, the plot view handle, the paper unit that fixes
/// the layout's coordinate system) is carried over from here untouched.
fn dialog_base_settings(&self) -> acadrust::objects::PlotSettings {
use acadrust::objects::{PlotPaperUnits, PlotSettings};
fn dialog_base_settings(&self) -> codec::objects::PlotSettings {
use codec::objects::{PlotPaperUnits, PlotSettings};
let scene = &self.tabs[self.active_tab].scene;
self.plot_setup_template
.clone()
@@ -3367,10 +3367,10 @@ impl OpenCADStudio {
/// settings both come from here so the two can never drift apart.
fn plot_settings_from_dialog(
&self,
mut ps: acadrust::objects::PlotSettings,
) -> acadrust::objects::PlotSettings {
mut ps: codec::objects::PlotSettings,
) -> codec::objects::PlotSettings {
use crate::io::paper_catalog::Orientation;
use acadrust::objects::{
use codec::objects::{
PlotPaperUnits, PlotType, ScaledType, ShadePlotMode, ShadePlotResolutionLevel,
};
let d = &self.plot_dialog;
@@ -3505,7 +3505,7 @@ impl OpenCADStudio {
let (x0, y0) = (-left * units_per_mm, -bottom * units_per_mm);
let (lw, lh) = (w * units_per_mm, h * units_per_mm);
for obj in self.tabs[i].scene.document.objects.values_mut() {
if let acadrust::objects::ObjectType::Layout(layout) = obj {
if let codec::objects::ObjectType::Layout(layout) = obj {
if layout.name == layout_name {
layout.min_limits = (x0, y0);
layout.max_limits = (x0 + lw, y0 + lh);
@@ -4084,7 +4084,7 @@ impl OpenCADStudio {
/// active page setup, no dialog. Model space only. (#325)
pub(crate) fn on_quick_print_handles(
&mut self,
handles: Vec<acadrust::Handle>,
handles: Vec<codec::Handle>,
) -> Task<Message> {
let i = self.active_tab;
if self.tabs[i].scene.current_layout != "Model" {
@@ -4092,7 +4092,7 @@ impl OpenCADStudio {
.push_error(crate::t!("Quick print works in model space.").as_ref());
return Task::none();
}
let set: std::collections::HashSet<acadrust::Handle> = handles.into_iter().collect();
let set: std::collections::HashSet<codec::Handle> = handles.into_iter().collect();
// Union the AABBs of the picked entities' wires (world XY), matched by
// each wire's handle.
let (x0, y0, x1, y1, any) = {
@@ -5019,14 +5019,14 @@ impl OpenCADStudio {
/// Build a `PlotSettings` from the current dialog fields (for saving a named
/// page setup).
/// The dialog's values as a named page setup.
fn dialog_to_plotsettings(&self) -> acadrust::objects::PlotSettings {
fn dialog_to_plotsettings(&self) -> codec::objects::PlotSettings {
self.plot_settings_from_dialog(self.dialog_base_settings())
}
/// Load a `PlotSettings` into the dialog editor fields.
pub(in crate::app) fn load_plotsettings_into_dialog(&mut self, ps: &acadrust::objects::PlotSettings) {
pub(in crate::app) fn load_plotsettings_into_dialog(&mut self, ps: &codec::objects::PlotSettings) {
use crate::io::paper_catalog::PaperUnits;
use acadrust::objects::{PlotType, ShadePlotMode, ShadePlotResolutionLevel};
use codec::objects::{PlotType, ShadePlotMode, ShadePlotResolutionLevel};
self.plot_setup_template = Some(ps.clone());
if matches!(ps.plot_type, PlotType::Window) && !ps.plot_window.is_empty() {
self.plot_window = Some((
@@ -5109,7 +5109,7 @@ impl OpenCADStudio {
}
d.center = ps.flags.plot_centered;
d.paper_units = match ps.paper_units {
acadrust::objects::PlotPaperUnits::Inches => PaperUnits::Inches,
codec::objects::PlotPaperUnits::Inches => PaperUnits::Inches,
_ => PaperUnits::Millimeters,
};
d.offset_x = trim_decimals(&format!("{:.4}", d.paper_units.from_mm(ps.origin_x)));
@@ -5671,7 +5671,7 @@ mod plot_paper_tests {
ps.paper_width = 297.0;
ps.paper_height = 210.0;
// Such drivers spell the orientation in the dimensions, not the rotation.
ps.rotation = acadrust::objects::PlotRotation::None;
ps.rotation = codec::objects::PlotRotation::None;
assert!(app.tabs[i].scene.set_layout_plot_settings("Layout1", &ps));
app
}
@@ -5681,21 +5681,21 @@ mod plot_paper_tests {
(ps.paper_size, ps.paper_width, ps.paper_height)
}
fn layout_settings(app: &OpenCADStudio) -> acadrust::objects::PlotSettings {
fn layout_settings(app: &OpenCADStudio) -> codec::objects::PlotSettings {
app.tabs[app.active_tab]
.scene
.plot_settings_for("Layout1")
.unwrap()
}
fn layout_rotation(app: &OpenCADStudio) -> acadrust::objects::PlotRotation {
fn layout_rotation(app: &OpenCADStudio) -> codec::objects::PlotRotation {
layout_settings(app).rotation
}
/// Store the drawing's plot settings for `Layout1` after `edit` touched them.
fn edit_layout_settings(
app: &mut OpenCADStudio,
edit: impl FnOnce(&mut acadrust::objects::PlotSettings),
edit: impl FnOnce(&mut codec::objects::PlotSettings),
) {
let i = app.active_tab;
let mut ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
@@ -5705,7 +5705,7 @@ mod plot_paper_tests {
#[test]
fn a_new_drawing_starts_with_a_compatible_default_layout() {
use acadrust::objects::{PlotRotation, PlotType, ScaledType};
use codec::objects::{PlotRotation, PlotType, ScaledType};
let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
let _ = app.update(Message::LayoutSwitch("Layout1".into()));
@@ -5729,7 +5729,7 @@ mod plot_paper_tests {
#[test]
fn orientation_is_stored_as_a_rotation_of_the_medium() {
use acadrust::objects::PlotRotation as R;
use codec::objects::PlotRotation as R;
use crate::ui::window::plot::PlotFlag;
// A newly picked sheet is the catalogue's portrait medium…
let portrait_medium = [
@@ -5777,7 +5777,7 @@ mod plot_paper_tests {
#[test]
fn standard_scales_are_written_by_code_and_others_as_ratios() {
use acadrust::objects::ScaledType;
use codec::objects::ScaledType;
let mut app = app_with_printer_named_sheet();
let _ = app.on_plot_dialog_open();
let _ = app.on_plot_dlg(PlotDlgMsg::Area("Extents".into()));
@@ -5825,7 +5825,7 @@ mod plot_paper_tests {
#[test]
fn a_metre_drawing_stores_the_millimetres_it_really_plots_per_unit() {
use acadrust::objects::ScaledType;
use codec::objects::ScaledType;
let mut app = app_with_printer_named_sheet();
// Insertion units: metres. "1:100" then plots 10 mm per drawing unit.
app.tabs[app.active_tab].scene.document.header.insertion_units = 6;
@@ -5845,7 +5845,7 @@ mod plot_paper_tests {
#[test]
fn an_inch_layout_keeps_its_unit_and_converts_the_scale() {
use acadrust::objects::{PlotPaperUnits, ScaledType};
use codec::objects::{PlotPaperUnits, ScaledType};
let mut app = app_with_printer_named_sheet();
edit_layout_settings(&mut app, |ps| ps.paper_units = PlotPaperUnits::Inches);
let _ = app.on_plot_dialog_open();
@@ -5908,8 +5908,8 @@ mod plot_paper_tests {
assert_eq!(layout.flags, named.flags);
assert_eq!(layout.shade_plot_mode, named.shade_plot_mode);
assert_eq!(layout.shade_plot_resolution, named.shade_plot_resolution);
assert_eq!(named.rotation, acadrust::objects::PlotRotation::Degrees270);
assert_eq!(named.scale_type, acadrust::objects::ScaledType::OneToFifty);
assert_eq!(named.rotation, codec::objects::PlotRotation::Degrees270);
assert_eq!(named.scale_type, codec::objects::ScaledType::OneToFifty);
}
#[test]
@@ -5952,7 +5952,7 @@ mod plot_paper_tests {
}
/// The page-setup fields the file format stores, minus handles.
fn stored_fields(ps: &acadrust::objects::PlotSettings) -> String {
fn stored_fields(ps: &codec::objects::PlotSettings) -> String {
format!(
"{} | {} | {:?} | {:.6} {:.6} | {:.6} {:.6} {:.6} {:.6} | {:.6} {:.6} | {} {} \
| {:.6} / {:.6} | {:.9} | {:?} | {:?} | {:?} {:?} {}",
@@ -5986,7 +5986,7 @@ mod plot_paper_tests {
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn fixture_page_setups_round_trip_through_the_dialog_unchanged() {
use acadrust::objects::{PlotRotation, ScaledType};
use codec::objects::{PlotRotation, ScaledType};
let mut app = app_with_fixture();
let a3_medium = (297.0106506347656, 419.9889831542968);
let arch_d_medium = (914.4000244140626, 609.5999755859375);
@@ -6031,7 +6031,7 @@ mod plot_paper_tests {
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn fixture_pdf_layout_takes_a_new_sheet_in_canonical_form() {
use acadrust::objects::{PaperMargin, PlotRotation};
use codec::objects::{PaperMargin, PlotRotation};
let mut app = app_with_fixture();
let _ = app.update(Message::LayoutSwitch("A4 1-100".into()));
let _ = app.on_plot_dialog_open();
@@ -6068,7 +6068,7 @@ mod plot_paper_tests {
#[test]
fn switching_the_page_setup_unit_respells_offsets_and_keeps_the_output() {
use acadrust::objects::{PlotPaperUnits, ScaledType};
use codec::objects::{PlotPaperUnits, ScaledType};
use crate::ui::window::plot::PlotFlag;
let mut app = app_with_printer_named_sheet();
let _ = app.on_plot_dialog_open();
@@ -6107,7 +6107,7 @@ mod plot_paper_tests {
#[test]
fn custom_scale_fields_follow_and_drive_the_picker() {
use acadrust::objects::ScaledType;
use codec::objects::ScaledType;
use crate::ui::window::plot::PlotFlag;
let mut app = app_with_printer_named_sheet();
let _ = app.on_plot_dialog_open();
@@ -6235,7 +6235,7 @@ mod plot_paper_tests {
assert_eq!(name, "A4", "the driver's own spelling must survive the dialog");
// …and so must the driver's landscape medium: unrotated, as stored.
assert_eq!((w, h), (297.0, 210.0));
assert_eq!(layout_rotation(&app), acadrust::objects::PlotRotation::None);
assert_eq!(layout_rotation(&app), codec::objects::PlotRotation::None);
}
#[test]
@@ -6248,7 +6248,7 @@ mod plot_paper_tests {
let (name, w, h) = layout_paper(&app);
assert_eq!(name, "ISO_A3_(297.00_x_420.00_MM)");
assert_eq!((w, h), (297.0, 420.0));
assert_eq!(layout_rotation(&app), acadrust::objects::PlotRotation::Degrees90);
assert_eq!(layout_rotation(&app), codec::objects::PlotRotation::Degrees90);
// The next dialog remembers the sheet the user chose.
assert_eq!(app.plot_paper.canonical, "ISO_A3_(297.00_x_420.00_MM)");
}
@@ -6262,7 +6262,7 @@ mod plot_paper_tests {
let ps = app.tabs[app.active_tab].scene.plot_settings_for("Layout1").unwrap();
assert_eq!(ps.printer_name, "DWG To PDF.pc3");
// A changed device takes the PDF driver's printable area for the sheet.
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(5.0, 17.0, 6.0, 18.0));
assert_eq!(ps.margins, codec::objects::PaperMargin::new(5.0, 17.0, 6.0, 18.0));
}
#[test]
@@ -6286,7 +6286,7 @@ mod plot_paper_tests {
let mut ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
ps.printer_name = "DWF6 ePlot.pc3".into();
ps.paper_size = "ISO_A4_(210.00_x_297.00_MM)".into();
ps.margins = acadrust::objects::PaperMargin::new(5.793749, 17.793753, 5.793744, 17.793747);
ps.margins = codec::objects::PaperMargin::new(5.793749, 17.793753, 5.793744, 17.793747);
assert!(app.tabs[i].scene.set_layout_plot_settings("Layout1", &ps));
let _ = app.on_plot_dialog_open();
assert!(app.plot_dialog.to_file, "an unknown plotter plots to PDF here");
@@ -6303,18 +6303,18 @@ mod plot_paper_tests {
let mut ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
ps.printer_name = "DWG To PDF.pc3".into();
ps.paper_size = "ISO_A4_(210.00_x_297.00_MM)".into();
ps.margins = acadrust::objects::PaperMargin::new(5.0, 17.0, 6.0, 18.0);
ps.margins = codec::objects::PaperMargin::new(5.0, 17.0, 6.0, 18.0);
assert!(app.tabs[i].scene.set_layout_plot_settings("Layout1", &ps));
let _ = app.on_plot_dialog_open();
let _ = app.on_plot_dlg(PlotDlgMsg::Paper("ISO_full_bleed_A4_(210.00_x_297.00_MM)".into()));
let _ = app.on_plot_dlg(PlotDlgMsg::SetCurrent);
let ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
assert_eq!(ps.paper_size, "ISO_full_bleed_A4_(210.00_x_297.00_MM)");
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(0.0, 1.0, 0.0, 1.0));
assert_eq!(ps.margins, codec::objects::PaperMargin::new(0.0, 1.0, 0.0, 1.0));
let _ = app.on_plot_dlg(PlotDlgMsg::Paper("ISO_A3_(297.00_x_420.00_MM)".into()));
let _ = app.on_plot_dlg(PlotDlgMsg::SetCurrent);
let ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(5.0, 17.0, 6.0, 18.0));
assert_eq!(ps.margins, codec::objects::PaperMargin::new(5.0, 17.0, 6.0, 18.0));
assert_eq!((ps.paper_width, ps.paper_height), (297.0, 420.0));
}
@@ -6364,8 +6364,8 @@ mod plot_paper_tests {
let ps = app.tabs[app.active_tab].scene.plot_settings_for("Layout1").unwrap();
assert_eq!(ps.paper_size, "Roll_24_(609.60_x_1500.00_MM)");
assert_eq!((ps.paper_width, ps.paper_height), (609.6, 1500.0));
assert_eq!(ps.rotation, acadrust::objects::PlotRotation::Degrees90);
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(3.0, 17.0, 6.0, 4.0));
assert_eq!(ps.rotation, codec::objects::PlotRotation::Degrees90);
assert_eq!(ps.margins, codec::objects::PaperMargin::new(3.0, 17.0, 6.0, 4.0));
// Re-adding the same size replaces the definition instead of duplicating it.
let _ = app.on_plot_dlg(custom(C::Open));
assert_eq!(app.plot_dialog.custom_editor.as_ref().map(|d| d.name.as_str()), Some("Roll 24"));
@@ -6485,7 +6485,7 @@ cupsPrintQuality/Print Quality: *Normal High\n";
assert_eq!(name, "Roll_24_(609.60_x_1500.00_MM)");
// The drawing's own landscape medium stays as it was stored.
assert_eq!((w, h), (1500.0, 609.6));
assert_eq!(layout_rotation(&app), acadrust::objects::PlotRotation::None);
assert_eq!(layout_rotation(&app), codec::objects::PlotRotation::None);
}
}
@@ -6502,7 +6502,7 @@ mod plot_device_persistence_tests {
let mut app = OpenCADStudio::new_for_test();
// A real drawing's layout carries plot settings with no device; the
// auto-applied setup used to reset the choice to the default.
let mut ps = acadrust::objects::PlotSettings::default();
let mut ps = codec::objects::PlotSettings::default();
ps.printer_name = String::new();
let layout = app.tabs[app.active_tab].scene.current_layout.clone();
assert!(
@@ -6528,7 +6528,7 @@ mod plot_device_persistence_tests {
fn layout_device_overrides_the_saved_preference() {
let mut app = OpenCADStudio::new_for_test();
app.plot_dialog.printer = Some("Brother DCP-L2520D series".into());
let mut ps = acadrust::objects::PlotSettings::default();
let mut ps = codec::objects::PlotSettings::default();
ps.printer_name = "Godex G500".into();
app.load_plotsettings_into_dialog(&ps);
assert_eq!(app.plot_dialog.printer.as_deref(), Some("Godex G500"));
@@ -6553,8 +6553,8 @@ mod plot_device_persistence_tests {
#[test]
fn layout_window_is_mirrored_into_the_dialog() {
let mut app = OpenCADStudio::new_for_test();
let mut ps = acadrust::objects::PlotSettings::default();
ps.plot_type = acadrust::objects::PlotType::Window;
let mut ps = codec::objects::PlotSettings::default();
ps.plot_type = codec::objects::PlotType::Window;
ps.set_plot_window(1.0, 2.0, 3.0, 4.0);
app.load_plotsettings_into_dialog(&ps);
assert_eq!(app.plot_window, Some((1.0, 2.0, 3.0, 4.0)));
@@ -6566,7 +6566,7 @@ mod plot_device_persistence_tests {
fn pdf_device_switches_to_file_output() {
let mut app = OpenCADStudio::new_for_test();
app.plot_dialog.printer = Some("Brother DCP-L2520D series".into());
let mut ps = acadrust::objects::PlotSettings::default();
let mut ps = codec::objects::PlotSettings::default();
ps.printer_name = "Microsoft Print to PDF".into();
app.load_plotsettings_into_dialog(&ps);
assert!(app.plot_dialog.to_file);
+69 -67
View File
@@ -613,6 +613,8 @@ impl OpenCADStudio {
self.control_screenshot(path, screenshot);
Task::none()
}
Message::Graph(message) => self.on_graph(message),
Message::ControlToggle => {
self.control.enabled = !self.control.enabled;
Task::none()
@@ -3061,24 +3063,24 @@ impl OpenCADStudio {
}
Message::LayerStateEditorMaskToggle(property) => {
let flag = match property {
super::LayerStateProperty::On => acadrust::LayerStateMask::ON,
super::LayerStateProperty::Frozen => acadrust::LayerStateMask::FROZEN,
super::LayerStateProperty::Locked => acadrust::LayerStateMask::LOCKED,
super::LayerStateProperty::Plot => acadrust::LayerStateMask::PLOT,
super::LayerStateProperty::On => codec::LayerStateMask::ON,
super::LayerStateProperty::Frozen => codec::LayerStateMask::FROZEN,
super::LayerStateProperty::Locked => codec::LayerStateMask::LOCKED,
super::LayerStateProperty::Plot => codec::LayerStateMask::PLOT,
super::LayerStateProperty::NewViewport => {
acadrust::LayerStateMask::NEW_VIEWPORT
codec::LayerStateMask::NEW_VIEWPORT
}
super::LayerStateProperty::Color => acadrust::LayerStateMask::COLOR,
super::LayerStateProperty::LineType => acadrust::LayerStateMask::LINE_TYPE,
super::LayerStateProperty::LineWeight => acadrust::LayerStateMask::LINE_WEIGHT,
super::LayerStateProperty::PlotStyle => acadrust::LayerStateMask::PLOT_STYLE,
super::LayerStateProperty::Color => codec::LayerStateMask::COLOR,
super::LayerStateProperty::LineType => codec::LayerStateMask::LINE_TYPE,
super::LayerStateProperty::LineWeight => codec::LayerStateMask::LINE_WEIGHT,
super::LayerStateProperty::PlotStyle => codec::LayerStateMask::PLOT_STYLE,
super::LayerStateProperty::Transparency => {
acadrust::LayerStateMask::TRANSPARENCY
codec::LayerStateMask::TRANSPARENCY
}
};
if let Some(state) = self.layer_state_edit_draft.as_mut() {
state.mask =
acadrust::LayerStateMask::from_bits(state.mask.bits() ^ flag.bits());
codec::LayerStateMask::from_bits(state.mask.bits() ^ flag.bits());
}
Task::none()
}
@@ -3627,7 +3629,7 @@ impl OpenCADStudio {
for name in &targets {
if let Some(layer) = self.tabs[i].scene.document.layers.get_mut(name) {
layer.transparency =
acadrust::types::Transparency::from_percent(v as f64 / 100.0);
codec::types::Transparency::from_percent(v as f64 / 100.0);
}
if let Some(pl) = self.tabs[i]
.layers
@@ -4409,9 +4411,9 @@ impl OpenCADStudio {
let values = if url.is_empty() {
None
} else {
let mut values = vec![acadrust::xdata::XDataValue::String(url)];
let mut values = vec![codec::xdata::XDataValue::String(url)];
if !description.is_empty() {
values.push(acadrust::xdata::XDataValue::String(description));
values.push(codec::xdata::XDataValue::String(description));
}
Some(values)
};
@@ -6570,19 +6572,19 @@ impl OpenCADStudio {
let i = self.active_tab;
let handles = self.property_target_handles(i);
self.apply_property_op(i, "CHPROP", &handles, |app, handle| {
if let Some(acadrust::EntityType::MultiLeader(leader)) =
if let Some(codec::EntityType::MultiLeader(leader)) =
app.tabs[i].scene.document.get_entity_mut(handle)
{
if field == "line_weight" {
leader.line_weight = value;
leader.property_override_flags.insert(
acadrust::entities::MultiLeaderPropertyOverrideFlags::LEADER_LINE_WEIGHT,
codec::entities::MultiLeaderPropertyOverrideFlags::LEADER_LINE_WEIGHT,
);
for root in &mut leader.context.leader_roots {
for line in &mut root.lines {
line.line_weight = value;
line.override_flags.insert(
acadrust::entities::LeaderLinePropertyOverrideFlags::LINE_WEIGHT,
codec::entities::LeaderLinePropertyOverrideFlags::LINE_WEIGHT,
);
}
}
@@ -6695,8 +6697,8 @@ impl OpenCADStudio {
"is_annotative" | "enable_annotation_scale" | "annotative_ctx" => {
let doc = &app.tabs[i].scene.document;
let cur = match doc.get_entity(handle) {
Some(acadrust::EntityType::MText(t)) => t.is_annotative,
Some(acadrust::EntityType::MultiLeader(m)) => {
Some(codec::EntityType::MText(t)) => t.is_annotative,
Some(codec::EntityType::MultiLeader(m)) => {
m.enable_annotation_scale
}
// TEXT (and any other context-only type): its
@@ -6738,7 +6740,7 @@ impl OpenCADStudio {
// only switches the panel to per-axis rows.
"ins_uniform" => {
let scales = match app.tabs[i].scene.document.get_entity(handle) {
Some(acadrust::EntityType::Insert(ins)) => {
Some(codec::EntityType::Insert(ins)) => {
Some((ins.x_scale(), ins.y_scale(), ins.z_scale()))
}
_ => None,
@@ -6750,7 +6752,7 @@ impl OpenCADStudio {
app.props_asym_scale.insert(handle.value());
} else {
app.props_asym_scale.remove(&handle.value());
if let Some(acadrust::EntityType::Insert(ins)) =
if let Some(codec::EntityType::Insert(ins)) =
app.tabs[i].scene.document.get_entity_mut(handle)
{
ins.set_y_scale(sx);
@@ -6761,7 +6763,7 @@ impl OpenCADStudio {
"tbl_title_suppressed" | "tbl_header_suppressed" => {
let next = {
let document = &app.tabs[i].scene.document;
let Some(acadrust::EntityType::Table(table)) =
let Some(codec::EntityType::Table(table)) =
document.get_entity(handle)
else {
return;
@@ -6770,7 +6772,7 @@ impl OpenCADStudio {
table.table_style_handle.and_then(|style_handle| {
document.objects.get(&style_handle).and_then(|object| {
match object {
acadrust::objects::ObjectType::TableStyle(
codec::objects::ObjectType::TableStyle(
style,
) => Some(style),
_ => None,
@@ -6811,7 +6813,7 @@ impl OpenCADStudio {
}
}
if field.starts_with("tbl_") {
if let Some(acadrust::EntityType::Table(table)) =
if let Some(codec::EntityType::Table(table)) =
app.tabs[i].scene.document.get_entity_mut(handle)
{
table.block_record_handle = None;
@@ -6828,20 +6830,20 @@ impl OpenCADStudio {
// Navigate the active vertex or table cell.
let n = if handles.len() == 1 {
match self.tabs[i].scene.document.get_entity(handles[0]) {
Some(acadrust::EntityType::LwPolyline(p)) => p.vertices.len(),
Some(acadrust::EntityType::Polyline2D(p)) => p.vertices.len(),
Some(acadrust::EntityType::PolygonMesh(p)) => p.vertices.len(),
Some(acadrust::EntityType::Face3D(face)) => {
Some(codec::EntityType::LwPolyline(p)) => p.vertices.len(),
Some(codec::EntityType::Polyline2D(p)) => p.vertices.len(),
Some(codec::EntityType::PolygonMesh(p)) => p.vertices.len(),
Some(codec::EntityType::Face3D(face)) => {
if face.is_triangle() {
3
} else {
4
}
}
Some(acadrust::EntityType::Polyline3D(p)) => {
Some(codec::EntityType::Polyline3D(p)) => {
crate::entities::polyline::polyline3d_control_vertex_count(p)
}
Some(acadrust::EntityType::Table(table)) => {
Some(codec::EntityType::Table(table)) => {
table.row_count().saturating_mul(table.column_count())
}
_ => 0,
@@ -6973,13 +6975,13 @@ impl OpenCADStudio {
if !handles.is_empty() {
self.apply_property_op(i, "CHPROP", &handles, |app, handle| {
match app.tabs[i].scene.document.get_entity_mut(handle) {
Some(acadrust::EntityType::MText(m)) => {
Some(codec::EntityType::MText(m)) => {
m.background_color = color.clone();
// Picking a colour turns the background on in Fill
// mode (specific colour), preserving the frame bit.
m.background_fill_flags = (m.background_fill_flags & !0x02) | 0x01;
}
Some(acadrust::EntityType::Hatch(h)) => {
Some(codec::EntityType::Hatch(h)) => {
crate::entities::hatch::set_background_color(h, &color);
}
_ => {}
@@ -7006,10 +7008,10 @@ impl OpenCADStudio {
let handles = self.property_target_handles(i);
if field == "indicator_fill_color" {
self.apply_property_op(i, "CHPROP", &handles, |app, handle| {
if let Some(acadrust::EntityType::Extended(extended)) =
if let Some(codec::EntityType::Extended(extended)) =
app.tabs[i].scene.document.get_entity_mut(handle)
{
if let acadrust::entities::ExtendedEntityData::SectionObject(data) =
if let codec::entities::ExtendedEntityData::SectionObject(data) =
&mut extended.data
{
data.indicator_color = color;
@@ -7033,8 +7035,8 @@ impl OpenCADStudio {
| "dim_text_fill_color"
) {
let fill_mode = (field == "dim_text_fill_color").then(|| match color {
acadrust::types::Color::None => 0,
acadrust::types::Color::ByBlock => 1,
codec::types::Color::None => 0,
codec::types::Color::ByBlock => 1,
_ => 2,
});
let aci = color.approximate_index();
@@ -7044,14 +7046,14 @@ impl OpenCADStudio {
"dim_text_fill_color" => crate::entities::dim_override::DIMTFILLCLR,
_ => crate::entities::dim_override::DIMCLRD,
};
let targets: Vec<acadrust::Handle> = handles
let targets: Vec<codec::Handle> = handles
.iter()
.copied()
.filter(|&h| {
matches!(
self.tabs[i].scene.document.get_entity(h),
Some(acadrust::EntityType::Leader(_))
| Some(acadrust::EntityType::Dimension(_))
Some(codec::EntityType::Leader(_))
| Some(codec::EntityType::Dimension(_))
)
})
.collect();
@@ -7062,7 +7064,7 @@ impl OpenCADStudio {
&mut app.tabs[i].scene.document,
handle,
crate::entities::dim_override::DIMTFILL,
Some(acadrust::xdata::XDataValue::Integer16(
Some(codec::xdata::XDataValue::Integer16(
fill_mode.unwrap_or(2),
)),
);
@@ -7074,7 +7076,7 @@ impl OpenCADStudio {
&mut app.tabs[i].scene.document,
handle,
code,
Some(acadrust::xdata::XDataValue::Integer16(aci)),
Some(codec::xdata::XDataValue::Integer16(aci)),
);
});
self.tabs[i].properties.open_color_field = None;
@@ -7086,20 +7088,20 @@ impl OpenCADStudio {
"line_color" | "text_color" | "block_content_color" | "background_fill_color"
) {
self.apply_property_op(i, "CHPROP", &handles, |app, handle| {
if let Some(acadrust::EntityType::MultiLeader(leader)) =
if let Some(codec::EntityType::MultiLeader(leader)) =
app.tabs[i].scene.document.get_entity_mut(handle)
{
match field.as_str() {
"line_color" => {
leader.line_color = color;
leader.property_override_flags.insert(
acadrust::entities::MultiLeaderPropertyOverrideFlags::LINE_COLOR,
codec::entities::MultiLeaderPropertyOverrideFlags::LINE_COLOR,
);
for root in &mut leader.context.leader_roots {
for line in &mut root.lines {
line.line_color = color;
line.override_flags.insert(
acadrust::entities::LeaderLinePropertyOverrideFlags::LINE_COLOR,
codec::entities::LeaderLinePropertyOverrideFlags::LINE_COLOR,
);
}
}
@@ -7108,14 +7110,14 @@ impl OpenCADStudio {
leader.text_color = color;
leader.context.text_color = color;
leader.property_override_flags.insert(
acadrust::entities::MultiLeaderPropertyOverrideFlags::TEXT_COLOR,
codec::entities::MultiLeaderPropertyOverrideFlags::TEXT_COLOR,
);
}
"block_content_color" => {
leader.block_content_color = color;
leader.context.block_content_color = color;
leader.property_override_flags.insert(
acadrust::entities::MultiLeaderPropertyOverrideFlags::BLOCK_CONTENT_COLOR,
codec::entities::MultiLeaderPropertyOverrideFlags::BLOCK_CONTENT_COLOR,
);
}
"background_fill_color" => {
@@ -7135,7 +7137,7 @@ impl OpenCADStudio {
let cell_index = self.tabs[i].properties.prop_vertex;
if !handles.is_empty() {
self.apply_property_op(i, "TABLE CELL COLOR", &handles, |app, handle| {
let Some(acadrust::EntityType::Table(table)) =
let Some(codec::EntityType::Table(table)) =
app.tabs[i].scene.document.get_entity_mut(handle)
else {
return;
@@ -7148,7 +7150,7 @@ impl OpenCADStudio {
cell_index / columns,
cell_index % columns,
) {
use acadrust::entities::table::CellStateFlags;
use codec::entities::table::CellStateFlags;
if cell.state.intersects(
CellStateFlags::FORMAT_LOCKED
| CellStateFlags::FORMAT_READ_ONLY,
@@ -7159,13 +7161,13 @@ impl OpenCADStudio {
if field == "tbl_cell_content_color" {
style.content_color = color;
style.property_flags.insert(
acadrust::entities::table::CellStylePropertyFlags::CONTENT_COLOR,
codec::entities::table::CellStylePropertyFlags::CONTENT_COLOR,
);
} else {
style.background_color = color;
style.fill_enabled = true;
style.property_flags.insert(
acadrust::entities::table::CellStylePropertyFlags::BACKGROUND_COLOR,
codec::entities::table::CellStylePropertyFlags::BACKGROUND_COLOR,
);
}
}
@@ -7178,7 +7180,7 @@ impl OpenCADStudio {
if !handles.is_empty() {
let idx = if field == "gradient_color_2" { 1 } else { 0 };
self.apply_property_op(i, "CHPROP", &handles, |app, handle| {
if let Some(acadrust::EntityType::Hatch(h)) =
if let Some(codec::EntityType::Hatch(h)) =
app.tabs[i].scene.document.get_entity_mut(handle)
{
while h.gradient_color.colors.len() <= idx {
@@ -7188,9 +7190,9 @@ impl OpenCADStudio {
1.0
};
h.gradient_color.colors.push(
acadrust::entities::hatch::GradientColorEntry {
codec::entities::hatch::GradientColorEntry {
value,
color: acadrust::types::Color::Index(7),
color: codec::types::Color::Index(7),
},
);
}
@@ -10053,7 +10055,7 @@ impl OpenCADStudio {
// ── TableStyle Dialog ─────────────────────────────────────────────
Message::TableStyleDialogOpen => {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let i = self.active_tab;
self.tablestyle_selected = self.tabs[i]
.scene
@@ -10116,7 +10118,7 @@ impl OpenCADStudio {
}
Message::TableStyleSetFlow(value) => {
use acadrust::objects::TableFlowDirection;
use codec::objects::TableFlowDirection;
let i = self.active_tab;
if let Some(s) = self.tablestyle_mut(i) {
s.flow_direction = match value.as_str() {
@@ -10176,7 +10178,7 @@ impl OpenCADStudio {
border,
value,
} => {
use acadrust::objects::TableBorderType;
use codec::objects::TableBorderType;
let i = self.active_tab;
if let Some(s) = self.tablestyle_mut(i) {
if let Some(bd) =
@@ -10214,7 +10216,7 @@ impl OpenCADStudio {
}
Message::TableStyleCellSetAlign { row, value } => {
use acadrust::objects::CellAlignment;
use codec::objects::CellAlignment;
let i = self.active_tab;
if let Some(s) = self.tablestyle_mut(i) {
if let Some(c) = Self::ts_cell_of(s, row) {
@@ -10237,7 +10239,7 @@ impl OpenCADStudio {
Message::TableStyleCellApply(row) => self.on_table_style_cell_apply(row),
Message::TableStyleToggle(field) => {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let i = self.active_tab;
let name = self.tablestyle_selected.clone();
for obj in self.tabs[i].scene.document.objects.values_mut() {
@@ -10255,7 +10257,7 @@ impl OpenCADStudio {
}
Message::TableStyleToggleAnnotative => {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let i = self.active_tab;
let name = self.tablestyle_selected.clone();
for obj in self.tabs[i].scene.document.objects.values_mut() {
@@ -10319,7 +10321,7 @@ impl OpenCADStudio {
Task::none()
}
Message::MlStyleDialogSetCurrent => {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let i = self.active_tab;
let name = self.mlstyle_selected.clone();
let exists = self.tabs[i]
@@ -10408,7 +10410,7 @@ impl OpenCADStudio {
if let Some(style) = self.mlstyle_mut(i) {
style
.elements
.push(acadrust::objects::MLineStyleElement::default());
.push(codec::objects::MLineStyleElement::default());
}
self.load_mlstyle_bufs(i);
Task::none()
@@ -10679,12 +10681,12 @@ impl OpenCADStudio {
}
}
pub(crate) fn note_recent_color(&mut self, color: acadrust::types::Color) {
pub(crate) fn note_recent_color(&mut self, color: codec::types::Color) {
// Keep only real colours in the recent list. ByLayer / ByBlock / None
// are logical CAD states rather than reusable colours.
if matches!(
&color,
acadrust::types::Color::Index(_) | acadrust::types::Color::Rgb { .. }
codec::types::Color::Index(_) | codec::types::Color::Rgb { .. }
) {
// No duplicates: selecting an existing colour moves it to the front.
if let Some(pos) = self.recent_colors.iter().position(|c| c == &color) {
@@ -10748,7 +10750,7 @@ impl OpenCADStudio {
/// selected style (staged, no commit), so edits survive switching as well
/// as Apply.
fn stage_tablestyle_bufs(&mut self) {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let i = self.active_tab;
let name = self.tablestyle_selected.clone();
let h: Option<f64> = self.ts_hmargin.trim().parse().ok();
@@ -10839,9 +10841,9 @@ mod free_text_entry_tests {
use super::Message;
use crate::app::{OpenCADStudio, TextEntryMode};
use crate::modules::annotate::table_cmd::TableCellEditCommand;
use acadrust::entities::Table;
use acadrust::types::Vector3;
use acadrust::{EntityType, Handle};
use codec::entities::Table;
use codec::types::Vector3;
use codec::{EntityType, Handle};
/// A test drawing with a 2×2 table and the cell editor active on [0,0],
/// seeded with `cell_text`.
+6 -6
View File
@@ -78,7 +78,7 @@ impl OpenCADStudio {
let Some(draft) = self.plot_dialog.import_draft.take() else {
return Task::none();
};
let chosen: Vec<(String, acadrust::objects::PlotSettings)> = draft
let chosen: Vec<(String, codec::objects::PlotSettings)> = draft
.selected()
.map(|(name, ps)| (name.to_string(), ps.clone()))
.collect();
@@ -113,7 +113,7 @@ impl OpenCADStudio {
/// as one undoable step. Returns the names imported.
pub(super) fn import_page_setups(
&mut self,
setups: Vec<(String, acadrust::objects::PlotSettings)>,
setups: Vec<(String, codec::objects::PlotSettings)>,
) -> Vec<String> {
if setups.is_empty() {
return Vec::new();
@@ -169,7 +169,7 @@ impl OpenCADStudio {
return Task::none();
}
};
let chosen: Vec<(String, acadrust::objects::PlotSettings)> = if names == "*" {
let chosen: Vec<(String, codec::objects::PlotSettings)> = if names == "*" {
available
} else {
let wanted: Vec<&str> = names.split(',').map(str::trim).collect();
@@ -218,7 +218,7 @@ mod tests {
/// The fixture's page setups as the chooser would hold them, read
/// through the same document reader the command uses.
fn fixture_setups() -> Vec<(String, acadrust::objects::PlotSettings)> {
fn fixture_setups() -> Vec<(String, codec::objects::PlotSettings)> {
let document = crate::io::load_file(std::path::Path::new(FIXTURE)).unwrap();
crate::scene::document_page_setups(&document)
}
@@ -242,7 +242,7 @@ mod tests {
#[test]
fn psetupin_imports_named_setups_from_a_saved_drawing() {
use acadrust::objects::PlotRotation;
use codec::objects::PlotRotation;
// Author a source drawing with two named setups and save it.
let dir = std::env::temp_dir().join(format!("ocs-psetupin-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
@@ -256,7 +256,7 @@ mod tests {
ps.paper_width = 297.0;
ps.paper_height = 420.0;
ps.rotation = PlotRotation::Degrees90;
ps.plot_view_handle = acadrust::Handle::new(0xBEEF);
ps.plot_view_handle = codec::Handle::new(0xBEEF);
app.tabs[i].scene.page_setup_save("Site", ps.clone());
ps.paper_size = "ISO_A2_(420.00_x_594.00_MM)".into();
app.tabs[i].scene.page_setup_save("Overview", ps);
+39 -39
View File
@@ -15,8 +15,8 @@ use crate::scene::{
self, hover_id, CubeRegion, Scene, VIEWCUBE_DRAW_PX, VIEWCUBE_PAD, VIEWCUBE_PX,
};
use crate::ui::PropertiesPanel;
use acadrust::types::Color as AcadColor;
use acadrust::{EntityType as AcadEntityType, Handle};
use codec::types::Color as AcadColor;
use codec::{EntityType as AcadEntityType, Handle};
use iced::time::Instant;
use iced::{mouse, Point, Task};
@@ -25,8 +25,8 @@ impl OpenCADStudio {
pub(in crate::app) fn mlstyle_mut(
&mut self,
tab: usize,
) -> Option<&mut acadrust::objects::MLineStyle> {
use acadrust::objects::ObjectType;
) -> Option<&mut codec::objects::MLineStyle> {
use codec::objects::ObjectType;
let name = self.mlstyle_selected.clone();
self.tabs[tab]
.scene
@@ -40,7 +40,7 @@ impl OpenCADStudio {
}
pub(in crate::app) fn load_mlstyle_bufs(&mut self, tab: usize) {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let name = self.mlstyle_selected.clone();
let Some((description, start_angle, end_angle, fill_color, elements)) = self.tabs[tab]
.scene
@@ -93,22 +93,22 @@ impl OpenCADStudio {
style.end_angle = value.to_radians();
}
if let Some(value) = fill_color {
style.fill_color = acadrust::types::Color::from_index(value);
style.fill_color = codec::types::Color::from_index(value);
}
for (element, values) in style.elements.iter_mut().zip(elements) {
if let Ok(value) = values[0].trim().parse::<f64>() {
element.offset = value;
}
if let Ok(value) = values[1].trim().parse::<i16>() {
element.color = acadrust::types::Color::from_index(value);
element.color = codec::types::Color::from_index(value);
}
element.linetype = values[2].clone();
}
}
}
pub(in crate::app) fn tablestyle_mut(&mut self, tab: usize) -> Option<&mut acadrust::objects::TableStyle> {
use acadrust::objects::ObjectType;
pub(in crate::app) fn tablestyle_mut(&mut self, tab: usize) -> Option<&mut codec::objects::TableStyle> {
use codec::objects::ObjectType;
let name = self.tablestyle_selected.clone();
self.tabs[tab]
.scene
@@ -124,9 +124,9 @@ impl OpenCADStudio {
/// Mutable access to a table style's cell style by row (0=Data,1=Header,2=Title).
pub(in crate::app) fn ts_cell_of(
s: &mut acadrust::objects::TableStyle,
s: &mut codec::objects::TableStyle,
row: u8,
) -> Option<&mut acadrust::objects::RowCellStyle> {
) -> Option<&mut codec::objects::RowCellStyle> {
match row {
0 => Some(&mut s.data_row_style),
1 => Some(&mut s.header_row_style),
@@ -139,9 +139,9 @@ impl OpenCADStudio {
/// (0=left 1=right 2=top 3=bottom 4=horizontal-inside 5=vertical-inside).
pub(in crate::app) fn ts_border_of(
c: &mut acadrust::objects::RowCellStyle,
c: &mut codec::objects::RowCellStyle,
border: u8,
) -> Option<&mut acadrust::objects::TableCellBorder> {
) -> Option<&mut codec::objects::TableCellBorder> {
match border {
0 => Some(&mut c.left_border),
1 => Some(&mut c.right_border),
@@ -156,7 +156,7 @@ impl OpenCADStudio {
/// Populate margin + per-cell edit buffers from the selected table style.
pub(in crate::app) fn load_tablestyle_bufs(&mut self, tab: usize) {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let name = self.tablestyle_selected.clone();
let Some(s) = self.tabs[tab]
.scene
@@ -211,8 +211,8 @@ impl OpenCADStudio {
/// Mutable access to the currently selected multileader style.
pub(in crate::app) fn mleaderstyle_mut(&mut self, tab: usize) -> Option<&mut acadrust::objects::MultiLeaderStyle> {
use acadrust::objects::ObjectType;
pub(in crate::app) fn mleaderstyle_mut(&mut self, tab: usize) -> Option<&mut codec::objects::MultiLeaderStyle> {
use codec::objects::ObjectType;
let name = self.mleaderstyle_selected.clone();
self.tabs[tab]
.scene
@@ -228,7 +228,7 @@ impl OpenCADStudio {
/// Populate all edit buffers from the currently selected multileader style.
pub(in crate::app) fn load_mleaderstyle_bufs(&mut self, tab: usize) {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let name = self.mleaderstyle_selected.clone();
let Some(s) = self.tabs[tab]
.scene
@@ -363,7 +363,7 @@ impl OpenCADStudio {
.text_styles
.get(&self.ds_dimtxsty)
.map(|style| style.handle)
.unwrap_or(acadrust::types::Handle::NULL);
.unwrap_or(codec::types::Handle::NULL);
let Some(ds) = doc.dim_styles.get_mut(&self.dimstyle_selected) else {
return;
};
@@ -465,12 +465,12 @@ impl OpenCADStudio {
// pictures are stale. Drop them and let each be drawn again. Without
// this an edit here would move the numbers and leave the drawing alone.
let edited = self.dimstyle_selected.clone();
let stale: Vec<acadrust::Handle> = self.tabs[tab]
let stale: Vec<codec::Handle> = self.tabs[tab]
.scene
.document
.entities()
.filter_map(|entity| match entity {
acadrust::EntityType::Dimension(dim)
codec::EntityType::Dimension(dim)
if dim.base().style_name.eq_ignore_ascii_case(&edited) =>
{
Some(entity.common().handle)
@@ -698,10 +698,10 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
c.text_height = h;
}
if let Some(v) = tc {
c.text_color = acadrust::types::Color::from_index(v);
c.text_color = codec::types::Color::from_index(v);
}
if let Some(v) = fc {
c.fill_color = acadrust::types::Color::from_index(v);
c.fill_color = codec::types::Color::from_index(v);
}
if let Some(v) = dtype {
c.data_type = v;
@@ -713,10 +713,10 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
for (b, (lw, color, spacing)) in border_vals.into_iter().enumerate() {
if let Some(bd) = Self::ts_border_of(c, b as u8) {
if let Some(v) = lw {
bd.line_weight = acadrust::types::LineWeight::from_value(v);
bd.line_weight = codec::types::LineWeight::from_value(v);
}
if let Some(v) = color {
bd.color = acadrust::types::Color::from_index(v);
bd.color = codec::types::Color::from_index(v);
}
if let Some(v) = spacing {
bd.double_line_spacing = v;
@@ -728,7 +728,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
}
pub(super) fn on_ml_style_dialog_open(&mut self) -> Task<Message> {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let i = self.active_tab;
let cur = self.tabs[i].scene.document.header.multiline_style.clone();
let exists = self.tabs[i]
@@ -761,7 +761,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
}
pub(super) fn on_mleader_style_dialog_open(&mut self) -> Task<Message> {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let i = self.active_tab;
let cur = self.tabs[i].active_mleader_style.clone();
let exists = self.tabs[i]
@@ -794,7 +794,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
}
pub(super) fn on_mleader_style_dialog_set_current(&mut self) -> Task<Message> {
use acadrust::objects::ObjectType;
use codec::objects::ObjectType;
let i = self.active_tab;
let name = self.mleaderstyle_selected.clone();
let exists = self.tabs[i]
@@ -847,7 +847,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
}
pub(super) fn on_mleader_style_set_enum(&mut self, field: &'static str, value: String) -> Task<Message> {
use acadrust::objects::{
use codec::objects::{
BlockContentConnectionType, LeaderContentType, LeaderDrawOrderType,
MultiLeaderDrawOrderType, MultiLeaderPathType, TextAlignmentType,
TextAngleType, TextAttachmentDirectionType, TextAttachmentType,
@@ -945,7 +945,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
pub(super) fn on_mleader_style_set_handle(&mut self, field: &'static str, value: String) -> Task<Message> {
let i = self.active_tab;
let doc = &self.tabs[i].scene.document;
let handle: Option<acadrust::types::Handle> = if value == "None"
let handle: Option<codec::types::Handle> = if value == "None"
|| value == "ByBlock"
|| value == "Closed filled"
{
@@ -1037,17 +1037,17 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
}
s.default_text = dt;
if let Some(v) = lc {
s.line_color = acadrust::types::Color::from_index(v);
s.line_color = codec::types::Color::from_index(v);
}
if let Some(v) = tc {
s.text_color = acadrust::types::Color::from_index(v);
s.text_color = codec::types::Color::from_index(v);
}
s.description = desc;
if let Some(v) = align {
s.align_space = v;
}
if let Some(v) = bclr {
s.block_content_color = acadrust::types::Color::from_index(v);
s.block_content_color = codec::types::Color::from_index(v);
}
if let Some(v) = brot {
s.block_content_rotation = v.to_radians();
@@ -1106,7 +1106,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
Task::none()
}
pub(super) fn on_color_window_pick(&mut self, color: acadrust::types::Color) -> Task<Message> {
pub(super) fn on_color_window_pick(&mut self, color: codec::types::Color) -> Task<Message> {
if matches!(
self.color_pick_target.as_ref().map(|(target, _)| target),
Some(crate::app::ColorPickTarget::PlotStyle)
@@ -1114,9 +1114,9 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
self.color_pick_target = None;
let rgb = match color {
acadrust::types::Color::Rgb { r, g, b } => Some((r, g, b)),
acadrust::types::Color::Index(index) => {
acadrust::types::aci_table::aci_to_rgb(index)
codec::types::Color::Rgb { r, g, b } => Some((r, g, b)),
codec::types::Color::Index(index) => {
codec::types::aci_table::aci_to_rgb(index)
}
_ => None,
};
@@ -1181,19 +1181,19 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
);
let doc = &self.tabs[i].scene.document;
let handle = if value == "Default" || value == "ByBlock" {
acadrust::types::Handle::NULL
codec::types::Handle::NULL
} else if is_lt {
doc.line_types
.iter()
.find(|lt| lt.name == value)
.map(|lt| lt.handle)
.unwrap_or(acadrust::types::Handle::NULL)
.unwrap_or(codec::types::Handle::NULL)
} else {
doc.block_records
.iter()
.find(|b| b.name == value)
.map(|b| b.handle)
.unwrap_or(acadrust::types::Handle::NULL)
.unwrap_or(codec::types::Handle::NULL)
};
// Staged: persists on Apply.
if let Some(ds) = self.tabs[i].scene.document.dim_styles.get_mut(&name) {
+36 -36
View File
@@ -18,8 +18,8 @@ use crate::scene::{
self, hover_id, CubeRegion, Scene, VIEWCUBE_DRAW_PX, VIEWCUBE_PAD, VIEWCUBE_PX,
};
use crate::ui::PropertiesPanel;
use acadrust::types::Color as AcadColor;
use acadrust::{EntityType as AcadEntityType, Handle};
use codec::types::Color as AcadColor;
use codec::{EntityType as AcadEntityType, Handle};
use iced::time::Instant;
use iced::{mouse, Point, Task};
use std::sync::Arc;
@@ -459,7 +459,7 @@ impl OpenCADStudio {
}
pub(in crate::app) fn sync_render_mode_to_active_tile(&mut self, i: usize) {
use acadrust::entities::ViewportRenderMode as M;
use codec::entities::ViewportRenderMode as M;
if self.tabs[i].scene.current_layout != "Model" {
return;
}
@@ -863,9 +863,9 @@ impl OpenCADStudio {
pub(super) fn on_set_render_mode(
&mut self,
mode: acadrust::entities::ViewportRenderMode,
mode: codec::entities::ViewportRenderMode,
) -> Task<Message> {
use acadrust::entities::ViewportRenderMode as M;
use codec::entities::ViewportRenderMode as M;
let i = self.active_tab;
let label = match mode {
M::Wireframe2D => "Wireframe 2D",
@@ -909,7 +909,7 @@ impl OpenCADStudio {
pub(super) fn on_cursor_moved(
&mut self,
p: Point,
expected_viewport: Option<acadrust::Handle>,
expected_viewport: Option<codec::Handle>,
) -> Task<Message> {
if self.color_pick_target.is_some() {
return Task::none();
@@ -2605,7 +2605,7 @@ impl OpenCADStudio {
} else {
self.tabs[i].scene.set_hover_highlight(None);
}
let hover_handle = hovered.unwrap_or(acadrust::Handle::NULL);
let hover_handle = hovered.unwrap_or(codec::Handle::NULL);
let wants_entity = self.tabs[i]
.active_cmd
.as_ref()
@@ -2973,12 +2973,12 @@ impl OpenCADStudio {
}
}
use acadrust::types::Vector3;
use codec::types::Vector3;
let v3 = |d: glam::DVec3| Vector3::new(d.x, d.y, d.z);
{
let ucs = self.tabs[i]
.active_ucs
.get_or_insert_with(|| acadrust::tables::Ucs::new("*ACTIVE*"));
.get_or_insert_with(|| codec::tables::Ucs::new("*ACTIVE*"));
match kind {
crate::app::UcsGripKind::Origin => {
ucs.origin = v3(world);
@@ -3065,7 +3065,7 @@ impl OpenCADStudio {
None
};
let same_basis =
|a: Option<&acadrust::tables::Ucs>, b: Option<&acadrust::tables::Ucs>| match (a, b) {
|a: Option<&codec::tables::Ucs>, b: Option<&codec::tables::Ucs>| match (a, b) {
(None, None) => true,
(Some(a), Some(b)) => {
a.origin == b.origin
@@ -4084,7 +4084,7 @@ impl OpenCADStudio {
if bounded_pick
&& matches!(
self.tabs[i].scene.document.get_entity(handle),
Some(acadrust::EntityType::Solid3D(_)),
Some(codec::EntityType::Solid3D(_)),
)
{
// The aperture caught an edge outside its face.
@@ -4102,7 +4102,7 @@ impl OpenCADStudio {
if uses_surface_point && entity_pick_point.is_finite() {
if matches!(
self.tabs[i].scene.document.get_entity(handle),
Some(acadrust::EntityType::Solid3D(_))
Some(codec::EntityType::Solid3D(_))
) {
self.tabs[i]
.scene
@@ -4173,7 +4173,7 @@ impl OpenCADStudio {
)
});
let (scale, angle) = match entity {
Some(acadrust::EntityType::Hatch(hatch)) => (
Some(codec::EntityType::Hatch(hatch)) => (
hatch.pattern_scale as f32,
hatch.pattern_angle.to_degrees() as f32,
),
@@ -5321,7 +5321,7 @@ properties={:.1}ms picked={}",
// If the double-click was not on editable text, keep the existing
// paper-space behaviour and try to enter the clicked viewport.
let wire_hit: Option<acadrust::Handle> = raw_wire_hit.and_then(|h| {
let wire_hit: Option<codec::Handle> = raw_wire_hit.and_then(|h| {
if let Some(AcadEntityType::Viewport(vp)) =
self.tabs[i].scene.document.get_entity(h)
{
@@ -5611,7 +5611,7 @@ properties={:.1}ms picked={}",
pub(super) fn on_viewport_click(
&mut self,
expected_viewport: Option<acadrust::Handle>,
expected_viewport: Option<codec::Handle>,
) -> Task<Message> {
let i = self.active_tab;
if self.tabs[i].scene.active_viewport != expected_viewport
@@ -5887,7 +5887,7 @@ properties={:.1}ms picked={}",
let is_solid = hovered.is_some_and(|handle| {
matches!(
self.tabs[i].scene.document.get_entity(handle),
Some(acadrust::EntityType::Solid3D(_)),
Some(codec::EntityType::Solid3D(_)),
)
});
// An aperture may catch an edge beside, rather than on, a face.
@@ -5903,7 +5903,7 @@ properties={:.1}ms picked={}",
.document
.entities()
.filter_map(|entity| {
matches!(entity, acadrust::EntityType::Solid3D(_))
matches!(entity, codec::EntityType::Solid3D(_))
.then_some(entity.common().handle)
})
.collect::<Vec<_>>();
@@ -6221,7 +6221,7 @@ properties={:.1}ms picked={}",
.map(|style| style.name.clone())
.unwrap_or_default();
for obj in self.tabs[i].scene.document.objects.values_mut() {
if let acadrust::objects::ObjectType::Layout(l) = obj {
if let codec::objects::ObjectType::Layout(l) = obj {
if l.name == new_name {
l.flags = layout_flags;
crate::scene::apply_default_page_setup(l, &plot_style);
@@ -6554,7 +6554,7 @@ mod selection_preview_tests {
#[test]
fn lower_endpoint_drag_previews_connected_tangent_profile_and_keeps_top_fixed() {
use crate::scene::parametric_constraints::{ConstraintKind, ParametricRef, ParametricScope};
use acadrust::{entities::{Arc, Line}, types::Vector3, EntityType};
use codec::{entities::{Arc, Line}, types::Vector3, EntityType};
let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
@@ -6676,7 +6676,7 @@ mod selection_preview_tests {
#[test]
fn grip_moves_keep_perpendicular_constraints_live_and_undoable() {
use crate::scene::parametric_constraints::{ConstraintKind, ParametricRef};
use acadrust::{entities::Line, types::Vector3, EntityType};
use codec::{entities::Line, types::Vector3, EntityType};
let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
@@ -6756,7 +6756,7 @@ mod selection_preview_tests {
#[test]
fn constrained_rectangle_grips_distinguish_perpendicular_corner_and_free_ends() {
use crate::scene::parametric_constraints::{ConstraintKind, ParametricRef, ParametricScope};
use acadrust::{entities::LwPolyline, types::Vector2, EntityType};
use codec::{entities::LwPolyline, types::Vector2, EntityType};
let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
@@ -6843,7 +6843,7 @@ mod selection_preview_tests {
#[test]
fn axis_constrained_line_grip_changes_length_and_translates_normal_to_axis() {
use crate::scene::parametric_constraints::{ConstraintKind, ParametricRef, ParametricScope};
use acadrust::{entities::Line, types::Vector3, EntityType};
use codec::{entities::Line, types::Vector3, EntityType};
for vertical in [false, true] {
let mut app = OpenCADStudio::new_for_test();
@@ -6878,7 +6878,7 @@ mod selection_preview_tests {
#[test]
fn xline_direction_grip_drag_changes_direction() {
use acadrust::{types::Vector3, EntityType};
use codec::{types::Vector3, EntityType};
let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
let i = app.active_tab;
@@ -6886,7 +6886,7 @@ mod selection_preview_tests {
// Base away from the model origin so the UCS icon cannot swallow
// the press (it sits at the origin in a fresh drawing).
let handle = app.tabs[i].scene.add_entity(EntityType::XLine(
acadrust::entities::XLine::new(
codec::entities::XLine::new(
Vector3::new(100.0, 50.0, 0.0),
Vector3::new(0.0, 1.0, 0.0),
),
@@ -6921,7 +6921,7 @@ mod selection_preview_tests {
#[test]
fn constraint_glyph_tooltip_appears_after_hover_dwell() {
use crate::scene::parametric_constraints::{ConstraintKind, ParametricRef, ParametricScope};
use acadrust::{entities::Line, types::Vector3, EntityType};
use codec::{entities::Line, types::Vector3, EntityType};
let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
@@ -6965,10 +6965,10 @@ mod selection_preview_tests {
#[cfg(target_os = "linux")]
#[test]
fn hyperlink_click_respects_existing_pointer_owners() {
use acadrust::entities::Line;
use acadrust::types::Vector3;
use acadrust::xdata::{ExtendedDataRecord, XDataValue};
use acadrust::EntityType;
use codec::entities::Line;
use codec::types::Vector3;
use codec::xdata::{ExtendedDataRecord, XDataValue};
use codec::EntityType;
use glam::DVec3;
for mode in ["link", "plain", "pan", "orbit", "zoom", "grip", "command"] {
@@ -7064,7 +7064,7 @@ mod selection_preview_tests {
/// point all carry the snapped Z instead of dropping to the XY plane.
#[test]
fn line_snap_to_3d_endpoint_keeps_elevation() {
use acadrust::{entities::Line, types::Vector3, EntityType};
use codec::{entities::Line, types::Vector3, EntityType};
use crate::snap::SnapType;
let mut app = OpenCADStudio::new_for_test();
@@ -7117,7 +7117,7 @@ mod selection_preview_tests {
/// separate 3D master toggle — the 2D Node mode must not catch them.
#[test]
fn line_snaps_to_box_corner() {
use acadrust::{entities::Solid3D, EntityType};
use codec::{entities::Solid3D, EntityType};
use crate::snap::SnapType;
let mut app = OpenCADStudio::new_for_test();
@@ -7212,7 +7212,7 @@ mod selection_preview_tests {
/// Vertex mode is configured — and the 2D system must not catch them.
#[test]
fn box_corner_ignores_3d_master_off() {
use acadrust::{entities::Solid3D, EntityType};
use codec::{entities::Solid3D, EntityType};
use crate::snap::SnapType;
let mut app = OpenCADStudio::new_for_test();
@@ -7280,7 +7280,7 @@ mod selection_preview_tests {
/// for the box's planar faces).
#[test]
fn line_snaps_to_box_face_center() {
use acadrust::{entities::Solid3D, EntityType};
use codec::{entities::Solid3D, EntityType};
use crate::snap::SnapType;
let mut app = OpenCADStudio::new_for_test();
@@ -7347,7 +7347,7 @@ mod selection_preview_tests {
/// Nearest-to-face catches an interior face point with no base point.
#[test]
fn line_snaps_to_box_face_nearest() {
use acadrust::{entities::Solid3D, EntityType};
use codec::{entities::Solid3D, EntityType};
use crate::snap::SnapType;
let mut app = OpenCADStudio::new_for_test();
@@ -7416,7 +7416,7 @@ mod selection_preview_tests {
/// grey-box (real mesh, real helper) since it needs no event plumbing.
#[test]
fn face_perpendicular_needs_base_and_interior_foot() {
use acadrust::{entities::Solid3D, EntityType};
use codec::{entities::Solid3D, EntityType};
let mut app = OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
@@ -7493,7 +7493,7 @@ mod selection_preview_tests {
/// Edge midpoints snap as their own 3D type at the segment centre.
#[test]
fn line_snaps_to_box_edge_midpoint() {
use acadrust::{entities::Solid3D, EntityType};
use codec::{entities::Solid3D, EntityType};
use crate::snap::SnapType;
let mut app = OpenCADStudio::new_for_test();
+3 -3
View File
@@ -5,7 +5,7 @@
use iced::Point;
use acadrust::types::Handle;
use codec::types::Handle;
use crate::app::OpenCADStudio;
use crate::scene::viewport_ref::{AcceptedSnap, ViewportFrame};
@@ -104,12 +104,12 @@ impl OpenCADStudio {
.scene
.document
.get_entity(source.source.handle),
Some(acadrust::EntityType::Insert(_))
Some(codec::EntityType::Insert(_))
) {
return true;
}
if source.snap_type == SnapType::Insertion {
let Some(acadrust::EntityType::Insert(insert)) = self.tabs[tab]
let Some(codec::EntityType::Insert(insert)) = self.tabs[tab]
.scene
.document
.get_entity(source.source.handle)