feat(props): editable block Name row + collapsible XYZ groups
- Block reference Name (Misc) is editable: the dropdown re-points the insert to another definition; typing a new name renames the definition everywhere (record re-key, Block marker, every INSERT reference). Anonymous (*) and xref blocks stay read-only, with the same guards added to Scene::rename_block. - Custom single-control dropdown (text field + caret) built on the shared floating_below overlay so the list always opens downward, unlike iced's space-based menu placement. - Consecutive "<Base> X/Y/Z" rows (Position, Scale, Start, Center, ...) collapse into one expandable summary row across all entities; the expand state persists across rebuilds and selection changes. - The BEDIT block tab no longer offers the layout Rename/Delete context menu. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
47f3409588
commit
b5dbef5776
10 changed files with 583 additions and 51 deletions
|
|
@ -229,15 +229,30 @@ impl Scene {
|
|||
|
||||
/// Rename a block definition: re-key its record, update the Block marker's
|
||||
/// name, and repoint every INSERT that referenced the old name so all
|
||||
/// instances keep resolving. Returns false if `old` is missing, `new` is
|
||||
/// already taken, or the names are equal (case-insensitive). (#261)
|
||||
/// instances keep resolving. Returns false if `old` is missing or
|
||||
/// anonymous/xref, `new` is invalid or already taken, or the names are
|
||||
/// equal (case-insensitive). (#261)
|
||||
pub fn rename_block(&mut self, old: &str, new: &str) -> bool {
|
||||
if !crate::scene::valid_block_name(new) {
|
||||
return false;
|
||||
}
|
||||
if old.eq_ignore_ascii_case(new) {
|
||||
return false;
|
||||
}
|
||||
if self.document.block_records.get(new).is_some() {
|
||||
return false;
|
||||
}
|
||||
// Anonymous (*) names are program-owned and re-numbered on save; an
|
||||
// xref('|') symbol name is bound to the referenced file.
|
||||
if self
|
||||
.document
|
||||
.block_records
|
||||
.get(old)
|
||||
.map(|br| br.is_anonymous() || br.flags.is_xref || br.name.contains('|'))
|
||||
.unwrap_or(true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
let Some(mut br) = self.document.block_records.remove(old) else {
|
||||
return false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -204,6 +204,20 @@ pub fn vp_effective_scale(custom_scale: f64, view_height: f64, vp_height: f64) -
|
|||
1.0
|
||||
}
|
||||
|
||||
/// A block name a user may assign: non-empty, no control characters, none of
|
||||
/// the symbol-table-reserved characters (`*` marks anonymous blocks, `|`
|
||||
/// xref-dependent ones; the rest are the DXF symbol-name exclusions).
|
||||
pub(crate) fn valid_block_name(name: &str) -> bool {
|
||||
!name.is_empty()
|
||||
&& !name.chars().any(|c| {
|
||||
c.is_control()
|
||||
|| matches!(
|
||||
c,
|
||||
'<' | '>' | '/' | '\\' | '"' | ':' | ';' | '?' | '*' | '|' | ',' | '=' | '`'
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Pre-built entity caches returned by [`build_derived_caches`].
|
||||
/// Produced in the file-load background task so the UI thread only assigns.
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
|||
|
|
@ -17,6 +17,13 @@ pub enum PropValue {
|
|||
selected: String,
|
||||
options: Vec<String>,
|
||||
},
|
||||
/// Editable text plus a dropdown of existing options (block reference
|
||||
/// Name row): picking an option re-points the reference, submitting a
|
||||
/// new name renames the definition.
|
||||
EditChoice {
|
||||
value: String,
|
||||
options: Vec<String>,
|
||||
},
|
||||
/// ACI/RGB/ByLayer/ByBlock color — rendered as a color picker.
|
||||
ColorChoice(AcadColor),
|
||||
/// Color varies across the current multi-selection.
|
||||
|
|
|
|||
|
|
@ -293,6 +293,7 @@ impl Scene {
|
|||
PropValue::ReadOnly(s) | PropValue::EditText(s) => s,
|
||||
PropValue::LayerChoice(s) => s,
|
||||
PropValue::Choice { selected, .. } => selected,
|
||||
PropValue::EditChoice { value, .. } => value,
|
||||
PropValue::ColorChoice(c) => Self::format_color(c),
|
||||
PropValue::LwChoice(lw) => Self::format_lineweight(lw),
|
||||
PropValue::LinetypeChoice(s) => s,
|
||||
|
|
|
|||
Loading…
Reference in a new issue