forked from 1b-agent/opencadstudio-upstream
Merge pull request #1627 from ramox81/codex/plotdate-refresh
Fields: evaluation events, UPDATEFIELD, FIELDEVAL, per-field shading and PlotDate redraw. # Conflicts: # Cargo.lock # src/entities/field.rs
This commit is contained in:
commit
711799371a
14 files changed
+533
-36
No files matched your search
@@ -848,6 +848,7 @@ impl OpenCADStudio {
|
||||
".{}.tmp.dwg",
|
||||
path.file_name().unwrap().to_string_lossy()
|
||||
));
|
||||
self.tabs[i].scene.update_fields(2, None);
|
||||
let document = self.tabs[i].scene.document_for_save();
|
||||
if let Err(e) = crate::io::save(&document, &scratch) {
|
||||
return err(format!("save: {e}"));
|
||||
|
||||
@@ -512,6 +512,8 @@ impl OpenCADStudio {
|
||||
}
|
||||
// Rebuild tessellation caches without modifying the document.
|
||||
"REGEN" | "REGENALL" => {
|
||||
// A regen is a field evaluation event (FIELDEVAL bit 16).
|
||||
self.tabs[i].scene.update_fields(16, None);
|
||||
self.tabs[i].scene.populate_meshes_from_document();
|
||||
self.command_line.push_output(crate::t!("REGEN: regenerated model.").as_ref());
|
||||
return Some(Task::none());
|
||||
|
||||
@@ -17,6 +17,80 @@ impl OpenCADStudio {
|
||||
self.open_field_dialog(FieldTarget::NewText);
|
||||
Some(Task::none())
|
||||
}
|
||||
// UPDATEFIELD — re-evaluate the fields of the selected objects
|
||||
// (a block reference's attributes included), whatever FIELDEVAL.
|
||||
"UPDATEFIELD" => {
|
||||
let selected: Vec<codec::Handle> =
|
||||
self.tabs[i].scene.selected_entities().into_iter().map(|(h, _)| h).collect();
|
||||
if selected.is_empty() {
|
||||
use crate::modules::draw::select::SelectObjectsCommand;
|
||||
let cmd = SelectObjectsCommand::new("UPDATEFIELD");
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
return Some(Task::none());
|
||||
}
|
||||
// A block reference brings its attributes and the fields of its
|
||||
// block definition; a table, the texts of its cells.
|
||||
let document = &self.tabs[i].scene.document;
|
||||
let mut hosts = selected.clone();
|
||||
for handle in &selected {
|
||||
let record = match document.get_entity(*handle) {
|
||||
Some(codec::EntityType::Insert(insert)) => {
|
||||
hosts.extend(insert.attributes.iter().map(|a| a.common.handle));
|
||||
document.block_records.iter().find(|r| r.name.eq_ignore_ascii_case(&insert.block_name))
|
||||
}
|
||||
Some(codec::EntityType::Table(table)) => table
|
||||
.block_record_handle
|
||||
.and_then(|h| document.block_records.iter().find(|r| r.handle == h)),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(record) = record {
|
||||
hosts.extend(record.entity_handles.iter().copied());
|
||||
}
|
||||
}
|
||||
self.push_undo_snapshot(i, "UPDATEFIELD");
|
||||
let found = self.tabs[i].scene.update_fields(32, Some(&hosts));
|
||||
self.tabs[i].scene.deselect_all();
|
||||
self.refresh_properties();
|
||||
if found > 0 {
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
self.command_line.push_output(crate::tf!("{} field(s) found.", found).as_ref());
|
||||
self.command_line.push_output(crate::tf!("{} field(s) updated.", found).as_ref());
|
||||
Some(Task::none())
|
||||
}
|
||||
// FIELDEVAL — the events that update fields, kept in the drawing.
|
||||
cmd if cmd == "FIELDEVAL" || cmd.starts_with("FIELDEVAL ") || cmd.starts_with("SETVAR FIELDEVAL") => {
|
||||
let value = cmd
|
||||
.trim_start_matches("SETVAR ")
|
||||
.trim_start_matches("FIELDEVAL")
|
||||
.trim();
|
||||
let current = crate::entities::field::fieldeval(&self.tabs[i].scene.document);
|
||||
let ask = |app: &mut Self| {
|
||||
app.command_line
|
||||
.push_output(&format!("Enter new value for FIELDEVAL <{current}>:"));
|
||||
app.pending_setvar = Some("FIELDEVAL".into());
|
||||
};
|
||||
match value.parse::<i32>() {
|
||||
_ if value.is_empty() => ask(self),
|
||||
Ok(n) if (0..=31).contains(&n) => {
|
||||
if n != current {
|
||||
self.push_undo_snapshot(i, "FIELDEVAL");
|
||||
crate::io::set_drawing_variable(
|
||||
&mut self.tabs[i].scene.document,
|
||||
"FIELDEVAL",
|
||||
&n.to_string(),
|
||||
);
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_error("Requires an integer between 0 and 31.");
|
||||
ask(self);
|
||||
}
|
||||
}
|
||||
Some(Task::none())
|
||||
}
|
||||
cmd if cmd == "_FIELD_OBJECT" || cmd.starts_with("_FIELD_OBJECT ") => {
|
||||
let handle = cmd
|
||||
.split_whitespace()
|
||||
|
||||
@@ -708,6 +708,8 @@ inventory::submit!(crate::command::CommandRegistration {
|
||||
"PDFOSNAP",
|
||||
"UOSNAP",
|
||||
"FIELDDISPLAY",
|
||||
"FIELDEVAL",
|
||||
"UPDATEFIELD",
|
||||
"PDFIMPORTMODE",
|
||||
"PDFIMPORTFILTER",
|
||||
"PDFIMPORTLAYERS",
|
||||
|
||||
+10
-3
@@ -2163,6 +2163,14 @@ impl OpenCADStudio {
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(in crate::app) fn prepare_native_save(&mut self, i: usize) {
|
||||
// A save is a field evaluation event (FIELDEVAL bit 2).
|
||||
self.tabs[i].scene.update_fields(2, None);
|
||||
self.prepare_snapshot_save(i);
|
||||
}
|
||||
|
||||
/// Bring the drawing state the file stores up to date, without the save
|
||||
/// event an autosave does not raise.
|
||||
pub(in crate::app) fn prepare_snapshot_save(&mut self, i: usize) {
|
||||
self.sync_view_state_for_save(i);
|
||||
sync_annotation_scale_header(&mut self.tabs[i].scene);
|
||||
self.stamp_header_sysvars(i);
|
||||
@@ -3297,7 +3305,7 @@ impl OpenCADStudio {
|
||||
if !self.tabs[i].dirty || self.active_save_jobs.contains_key(&self.tabs[i].id) {
|
||||
continue;
|
||||
}
|
||||
self.prepare_native_save(i);
|
||||
self.prepare_snapshot_save(i);
|
||||
let version = self.tabs[i].scene.document.version;
|
||||
let target = self.autosave_target(i);
|
||||
tasks.push(self.queue_native_save(
|
||||
@@ -3800,8 +3808,7 @@ impl OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
let hosts = crate::entities::field::stamp_plot_fields(&mut self.tabs[i].scene.document);
|
||||
if !hosts.is_empty() {
|
||||
let changes: Vec<_> = hosts.into_iter().map(|h| (h, crate::scene::ChangeKind::Modified)).collect();
|
||||
self.tabs[i].scene.bump_entities(&changes);
|
||||
self.tabs[i].scene.bump_text_hosts(&hosts);
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user