Files
OneCAD-Draft/src/entities/view_symbol.rs
T

254 lines
8.9 KiB
Rust

use acadrust::entities::{SectionSymbol, ViewBorder};
use crate::t;
use crate::command::EntityTransform;
use crate::entities::common::{edit_angle_prop, edit_prop, parse_f64, ro_prop, square_grip};
use crate::entities::traits::{Grippable, PropertyEditable, Transformable};
use crate::scene::model::object::{GripApply, GripDef, PropSection};
fn handle_text(handle: acadrust::Handle) -> String {
if handle.is_null() {
"None".to_string()
} else {
format!("{:X}", handle.value())
}
}
fn vector_text(vector: &acadrust::types::Vector3) -> String {
format!("{:.6}, {:.6}, {:.6}", vector.x, vector.y, vector.z)
}
fn apply_entity_transform<T: acadrust::Entity>(entity: &mut T, transform: &EntityTransform) {
crate::scene::view::transform::apply_standard_entity_transform(
entity,
transform,
|entity, first, second| {
entity.apply_transform(
&crate::scene::view::transform::reflection_about_xy_line(first, second),
);
},
);
}
impl Grippable for SectionSymbol {
fn grips(&self) -> Vec<GripDef> {
self.points
.iter()
.enumerate()
.map(|(index, point)| {
square_grip(
index,
glam::DVec3::new(point.point.x, point.point.y, point.point.z),
)
})
.collect()
}
fn apply_grip(&mut self, grip_id: usize, apply: GripApply) {
let Some(point) = self.points.get_mut(grip_id) else {
return;
};
match apply {
GripApply::Translate(delta) => {
point.point.x += delta.x;
point.point.y += delta.y;
point.point.z += delta.z;
}
GripApply::Absolute(position) => {
point.point =
acadrust::types::Vector3::new(position.x, position.y, position.z);
}
}
self.sync_display_fields();
}
}
impl PropertyEditable for SectionSymbol {
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
let point_data = self
.points
.iter()
.enumerate()
.map(|(index, point)| {
format!(
"{}: point [{}]; bulge {:.6}; label {:?}; offset [{}]; flag {}",
index + 1,
vector_text(&point.point),
point.bulge,
point.label,
vector_text(&point.label_offset),
point.raw_flag_280
)
})
.collect::<Vec<_>>()
.join("\n");
vec![
PropSection {
title: t!("Section Symbol").into_owned(),
props: vec![
edit_prop(t!("Symbol Scale").as_ref(), "section_scale", self.symbol_scale),
ro_prop(t!("View Symbol Version").as_ref(),
"section_view_version",
self.view_symbol_version.to_string(),
),
ro_prop(t!("Version").as_ref(), "section_version", self.version.to_string()),
ro_prop(t!("Style").as_ref(),
"section_style",
handle_text(self.style_handle),
),
ro_prop(t!("View Representation").as_ref(),
"section_view_rep",
handle_text(self.view_rep_handle),
),
ro_prop(t!("View Symbol Flags").as_ref(),
"section_view_flags",
self.raw_view_symbol_70.to_string(),
),
ro_prop(t!("Point Count").as_ref(),
"section_point_count",
self.points.len().to_string(),
),
ro_prop(t!("Stored Point Counts").as_ref(),
"section_raw_counts",
format!(
"{}, {}, flags {}",
self.raw_point_count_90,
self.raw_point_record_count,
self.raw_flags_90
),
),
ro_prop(t!("Identifier").as_ref(), "section_label", self.label.clone()),
],
},
PropSection {
title: t!("Section Points").into_owned(),
props: vec![ro_prop(t!("Records").as_ref(), "section_points", point_data)],
},
]
}
fn apply_geom_prop(&mut self, field: &str, value: &str) {
if field == "section_scale" {
if let Some(value) = parse_f64(value) {
self.symbol_scale = value.max(0.0);
}
}
}
}
impl Transformable for SectionSymbol {
fn apply_transform(&mut self, transform: &EntityTransform) {
apply_entity_transform(self, transform);
self.sync_display_fields();
}
}
impl Grippable for ViewBorder {
fn grips(&self) -> Vec<GripDef> {
vec![
square_grip(0, glam::DVec3::new(self.min[0], self.min[1], 0.0)),
square_grip(1, glam::DVec3::new(self.max[0], self.max[1], 0.0)),
square_grip(2, glam::DVec3::new(self.center[0], self.center[1], 0.0)),
]
}
fn apply_grip(&mut self, grip_id: usize, apply: GripApply) {
let delta = match apply {
GripApply::Translate(delta) => delta,
GripApply::Absolute(position) => {
let current = match grip_id {
0 => glam::DVec3::new(self.min[0], self.min[1], 0.0),
1 => glam::DVec3::new(self.max[0], self.max[1], 0.0),
2 => glam::DVec3::new(self.center[0], self.center[1], 0.0),
_ => return,
};
position - current
}
};
match grip_id {
0 => {
self.min[0] += delta.x;
self.min[1] += delta.y;
}
1 => {
self.max[0] += delta.x;
self.max[1] += delta.y;
}
2 => {
self.min[0] += delta.x;
self.min[1] += delta.y;
self.max[0] += delta.x;
self.max[1] += delta.y;
}
_ => return,
}
self.center = [
(self.min[0] + self.max[0]) * 0.5,
(self.min[1] + self.max[1]) * 0.5,
];
}
}
impl PropertyEditable for ViewBorder {
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
vec![PropSection {
title: t!("Drawing View").into_owned(),
props: vec![
edit_prop(t!("Center X").as_ref(), "view_border_x", self.center[0]),
edit_prop(t!("Center Y").as_ref(), "view_border_y", self.center[1]),
ro_prop(t!("Width").as_ref(),
"view_border_width",
format!("{:.6}", self.max[0] - self.min[0]),
),
ro_prop(t!("Height").as_ref(),
"view_border_height",
format!("{:.6}", self.max[1] - self.min[1]),
),
edit_prop(t!("Scale").as_ref(), "view_border_scale", self.scale),
edit_angle_prop(t!("Rotation").as_ref(),
"view_border_rotation",
self.rotation_angle.to_degrees(),
),
ro_prop(t!("Version").as_ref(), "view_border_version", self.version.to_string()),
ro_prop(t!("Active Viewport").as_ref(),
"view_border_viewport",
handle_text(self.active_viewport),
),
ro_prop(t!("Scale Object").as_ref(),
"view_border_scale_handle",
handle_text(self.scale_handle),
),
],
}]
}
fn apply_geom_prop(&mut self, field: &str, value: &str) {
let Some(value) = parse_f64(value) else {
return;
};
match field {
"view_border_x" => {
let delta = value - self.center[0];
self.min[0] += delta;
self.max[0] += delta;
self.center[0] = value;
}
"view_border_y" => {
let delta = value - self.center[1];
self.min[1] += delta;
self.max[1] += delta;
self.center[1] = value;
}
"view_border_scale" => self.scale = value.max(0.0),
"view_border_rotation" => self.rotation_angle = value.to_radians(),
_ => {}
}
}
}
impl Transformable for ViewBorder {
fn apply_transform(&mut self, transform: &EntityTransform) {
apply_entity_transform(self, transform);
}
}