diff --git a/src/app/commands/count.rs b/src/app/commands/count.rs index 4a30a0c10..754b6db80 100644 --- a/src/app/commands/count.rs +++ b/src/app/commands/count.rs @@ -183,7 +183,7 @@ impl OpenCADStudio { .count .as_ref() .filter(|m| m.target.is_some()) - .map(|m| m.result(&self.tabs[i].scene.document).counted.len()) + .map(|m| m.count(&self.tabs[i].scene.document)) .unwrap_or(0), ), "COUNTPALETTESTATE" => Some(self.count_palette.show as usize), @@ -374,9 +374,12 @@ impl OpenCADStudio { .collect(), _ => Vec::new(), }; - if targets.is_empty() && matches!(area_tokens.first(), Some(&"C") | Some(&"E") | None) { + // List all blocks: the palette, counting in the area when one was drawn. + if targets.is_empty() { self.set_count_palette(true); - return; + if matches!(area_tokens.first(), Some(&"C") | Some(&"E") | None) { + return; + } } let Some((area, boundary)) = self.resolve_count_area(i, area_tokens) else { return; @@ -403,7 +406,7 @@ impl OpenCADStudio { } let mode = CountMode { area, boundary, target, cursor: None, epoch: 0 }; if let Some(name) = mode.target_name() { - let n = mode.result(&self.tabs[i].scene.document).counted.len(); + let n = mode.count(&self.tabs[i].scene.document); self.command_line.push_output(&format!("{name} ...... {n}")); } self.tabs[i].count = Some(mode); diff --git a/src/app/control/actions.rs b/src/app/control/actions.rs index e39367343..e49f72008 100644 --- a/src/app/control/actions.rs +++ b/src/app/control/actions.rs @@ -1088,6 +1088,8 @@ impl OpenCADStudio { "link_text" => F::HyperlinkText(v.into()), "link_url" => F::HyperlinkUrl(v.into()), "plot_scale" => F::PlotScale(index(codec::fields::PLOT_SCALE_FORMATS.len())?), + "count" => F::CountExpression(v.into()), + "show_instances" => F::ShowCountInstances, _ => return Err(failure("invalid_value", "Unknown field dialog key")), }) } diff --git a/src/ui/window/count_palette.rs b/src/ui/window/count_palette.rs index 7da66744c..877ad92c0 100644 --- a/src/ui/window/count_palette.rs +++ b/src/ui/window/count_palette.rs @@ -96,6 +96,15 @@ impl CountMode { } } + /// What the count shows: the counted references, or 1 for a group whose + /// objects all exist. + pub fn count(&self, doc: &CadDocument) -> usize { + match &self.target { + Some(CountTarget::Group(handles)) => usize::from(handles.iter().all(|h| doc.get_entity(*h).is_some())), + _ => self.result(doc).counted.len(), + } + } + /// The name the toolbar and the command line show for the target. pub fn target_name(&self) -> Option { match &self.target { @@ -421,7 +430,7 @@ fn mode_view<'a>(palette: &'a CountPalette, mode: &'a CountMode, doc: &CadDocume let mut details = column![button( row![ crate::ui::icons::themed_success(CHECK_ICON, 12.0), - text(format!("{name}: {}", result.counted.len())).size(12).width(Fill), + text(format!("{name}: {}", mode.count(doc))).size(12).width(Fill), ] .spacing(6) .align_y(iced::Center), @@ -504,7 +513,7 @@ fn bar_button<'a>(icon: Element<'a, Message>, tip: String, m: Option) pub fn toolbar<'a>(mode: &CountMode, doc: &CadDocument) -> Element<'a, Message> { let has_target = mode.target.is_some(); let result = mode.result(doc); - let count = if has_target { result.counted.len().to_string() } else { "-".to_string() }; + let count = if has_target { mode.count(doc).to_string() } else { "-".to_string() }; let status: Element<'a, Message> = if !result.errors.is_empty() { crate::ui::icons::themed_warning(WARNING_ICON, 14.0) } else if has_target {