graphic design tool
git clone https://git.lucas.co/cce-designer.git
feat: added nodes start with their display flag off
Under the one-visible-per-directory rule, showing geometry is an
explicit act ('e' or the click toggle), never a side effect of adding:
both add routes — AddNode (palette/MCP/menu) and Ctrl+V paste — now
clear the new node's top-level geometry_visible. A subnet template's
internal chain keeps its own flags, so the node displays normally once
enabled. The serde default stays true so existing saves load unchanged.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/app.rs | 4 ++++
src/main.rs | 22 ++++++++++++++++++++++
src/window.rs | 6 ++++++
3 files changed, 32 insertions(+)
diff --git a/src/app.rs b/src/app.rs
index 89392c5..1d40728 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -6364,6 +6364,10 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec
let start_y = self.grid_cursor_row as f32;
let (nx, ny) = self.find_empty_cell(start_x, start_y, None);
node.position = (nx, ny);
+ // Added = hidden, same as AddNode: a
+ // paste of a displayed node must not
+ // become a second visible sibling.
+ node.geometry_visible = false;
self.current_dir_mut().children.push(node);
self.grid_cursor_col = nx as i32;
self.grid_cursor_row = ny as i32;
diff --git a/src/main.rs b/src/main.rs
index fe7ba7a..f9d6c90 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -182,6 +182,28 @@ mod tests {
assert!(dir.children[2].geometry_visible);
}
+ /// A newly added node arrives with its display flag OFF: under the
+ /// one-visible-per-directory rule, showing geometry is an explicit act,
+ /// never a side effect of adding. Template children keep their own flags
+ /// (a subnet's internal chain still displays once the parent is enabled).
+ #[test]
+ fn test_added_nodes_start_hidden() {
+ let mut state = State::new(false);
+ let mut redraw = false;
+ state
+ .apply_action(
+ McpAction::AddNode { template_name: "Sphere".to_string(), name: None, x: 5.0, y: 5.0 },
+ &mut redraw,
+ )
+ .expect("add sphere node");
+ let added = state.current_dir().children.last().unwrap();
+ assert!(!added.geometry_visible, "added node must start hidden");
+ assert!(
+ added.children.iter().any(|c| c.geometry_visible),
+ "the template's internal chain must keep its own flags"
+ );
+ }
+
/// The button must exist on Main, inside the File section, before Exit.
#[test]
fn test_main_node_offers_set_as_default() {
diff --git a/src/window.rs b/src/window.rs
index 1ada59a..7e45284 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -815,6 +815,12 @@ impl State {
node.name = state.get_lowest_unused_name(&node.name);
}
crate::app::ensure_meta_on(&mut node);
+ // New nodes arrive with their display flag OFF: the
+ // one-visible-per-directory rule means showing is an
+ // explicit act ('e', the click toggle), never a side
+ // effect of adding. Top-level flag only — a subnet
+ // template's internal chain keeps its own flags.
+ node.geometry_visible = false;
state.current_dir_mut().children.push(node);
state.sync_nodes();
state.rebuild_positions();