graphic design tool
git clone https://git.lucas.co/cce-designer.git
refactor: a camera node has no Square Aspect or Show Camera Pivot
Both were written onto the active camera when the viewport's toggles
flipped, and read by nothing: the settings are the viewport's and ride
the project's view state. The params, their writer and its two calls
are gone, and the merge drops them from a save that still has them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CLAUDE.md | 3 +--
nodes/camera.json | 12 ------------
src/app.rs | 38 +++++++-------------------------------
src/main.rs | 24 ++++++++++++++++++++++--
4 files changed, 30 insertions(+), 47 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index d4b88a0..5b5757a 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -532,8 +532,7 @@ save writes `ProjectViewState::display` — a `DisplaySettings`, the viewport
and render blocks of `DesignSettings` without the startup pointer, taken by
`State::display_settings` (which `save_settings` builds from as well) — and
both `load_from_file` paths apply it through `apply_display_settings`, before
-the Default Camera view so a camera node's own Square Aspect and pivot
-still win. The apply sets every field, regenerates the baked meshes, relays
+the Default Camera view so a camera node's own Pivot still wins. The apply sets every field, regenerates the baked meshes, relays
the two pane-shaped ones (network plate, circular pane), re-checks the
menubar marks, and saves state.kdl, so state.kdl holds the LAST-USED look:
what New and an older save (no block, which changes nothing) open with.
diff --git a/nodes/camera.json b/nodes/camera.json
index eb168e4..3a5a743 100644
--- a/nodes/camera.json
+++ b/nodes/camera.json
@@ -27,18 +27,6 @@
"min": -10.0,
"max": 10.0,
"description": "The point in world units the camera looks at and orbits around. Panning and framing move it."
- },
- {
- "name": "Square Aspect",
- "type": "toggle",
- "default": "false",
- "description": "Records the viewport's Square Aspect setting (a 1:1 view) for this camera; it is updated when that toggle is flipped while this camera is active."
- },
- {
- "name": "Show Camera Pivot",
- "type": "toggle",
- "default": "false",
- "description": "Records the viewport's Show Camera Pivot setting for this camera; it is updated when that toggle is flipped while this camera is active."
}
]
}
diff --git a/src/app.rs b/src/app.rs
index 4c31883..febd3e9 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1135,6 +1135,13 @@ pub fn merge_template_defs(root: &mut FsNode, templates: &[NodeTemplate]) {
}
}
fn merge_node(node: &mut FsNode, templates: &[NodeTemplate]) {
+ // A camera's Square Aspect and Show Camera Pivot were written when
+ // the viewport's toggles flipped under it and read by nothing: the
+ // settings are the viewport's, and ride the project's view state.
+ // Retired, and dropped from a save that still has them.
+ if node.node_type == "camera" {
+ node.params.retain(|p| p.name != "Square Aspect" && p.name != "Show Camera Pivot");
+ }
// Visualize's Mix blend was Set under another name (Opacity fades
// every blend alike) and is retired; a save holding it is Set, or
// it would load as a choice the row no longer offers.
@@ -4428,34 +4435,6 @@ impl State {
true
}
- /// Rewrite the Main node's setting toggles from live app state, so the
- /// switches show the real value even after panes/settings were changed
- /// through the menus or keyboard while another node was selected.
- /// Write a per-camera display toggle (Square Aspect / Show Camera Pivot)
- /// back to the ACTIVE camera node — the setting's home — so the next
- /// settings apply doesn't revert a menu/shortcut flip. No-op under
- /// Default Camera, which has no node: the live value stands alone.
- fn write_active_camera_toggle(&mut self, name: &str, val: bool) {
- if self.active_camera == "Default Camera" {
- return;
- }
- let active = self.active_camera.clone();
- if let Some(cam) = self
- .current_dir_mut()
- .children
- .iter_mut()
- .find(|c| c.node_type == "camera" && c.name == active)
- {
- if let Some(p) = cam.params.iter_mut().find(|p| p.name == name) {
- p.set_value(crate::app::ParamValue::Bool(val));
- }
- }
- }
-
-
-
-
-
pub fn sync_parameters_pane(&mut self) {
// Selection reads through the param-editor accessors: whichever
// network editor took the last node click feeds the pane, at ITS
@@ -9054,7 +9033,6 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
Action::ToggleCameraPivot => {
let val = !self.viewport().show_camera_pivot;
self.viewport_mut().show_camera_pivot = val;
- self.write_active_camera_toggle("Show Camera Pivot", val);
self.menu_mut(RIGHT_MENUBAR_IDX).set_item_checked(GUIDES_MENU, GUIDE_CAMERA_PIVOT, val);
settings_changed = true;
}
@@ -9141,8 +9119,6 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
}
Action::ToggleSquareViewport => {
self.square_viewport = !self.square_viewport;
- let val = self.square_viewport;
- self.write_active_camera_toggle("Square Aspect", val);
settings_changed = true;
}
Action::ToggleConfigure => {
diff --git a/src/main.rs b/src/main.rs
index 2bc4d56..076ba42 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4967,6 +4967,26 @@ mod tests {
.expect("a known kind is added");
}
+ /// A camera node has no Square Aspect or Show Camera Pivot: they were
+ /// written when the viewport's toggles flipped under it and read by
+ /// nothing. A save that has them loads without them.
+ #[test]
+ fn a_camera_carries_no_viewport_toggles() {
+ let templates_root = crate::app::load_fs_tree();
+ let templates = crate::app::flatten_node_templates(&templates_root);
+ let t = templates_root.children.iter().find(|t| t.node_type == "camera").unwrap();
+ let names: Vec<&str> = t.params.iter().map(|p| p.name.as_str()).collect();
+ assert_eq!(names, ["Position", "Rotation", "Pivot"]);
+ let mut old = t.clone();
+ old.params.push(crate::app::ParamDef::new("Square Aspect", "toggle", "true"));
+ old.params.push(crate::app::ParamDef::new("Show Camera Pivot", "toggle", "true"));
+ let mut root = templates_root.clone();
+ root.children = vec![old];
+ crate::app::merge_template_defs(&mut root, &templates);
+ let names: Vec<&str> = root.children[0].params.iter().map(|p| p.name.as_str()).collect();
+ assert_eq!(names, ["Position", "Rotation", "Pivot"]);
+ }
+
/// Visualize's Blend has no Mix: it was Set under another name, Opacity
/// fading every blend alike. A save that chose it loads as Set, a
/// valid choice, rather than as a text the row no longer offers.
@@ -6744,8 +6764,8 @@ mod tests {
let _ = std::fs::remove_dir_all(&dir);
let mut a = State::new(false);
- // The Default Camera is active: a camera NODE's own Square Aspect and
- // pivot params would override the saved view's, by design.
+ // The Default Camera is active: a camera NODE's own Pivot would
+ // override the saved view's, by design.
a.active_camera = "Default Camera".to_string();
a.square_viewport = true;
a.viewport_mut().show_camera_pivot = true;