git.lucas.co / cce-designer
graphic design tool
git clone https://git.lucas.co/cce-designer.git

commit15fb05424863c05388842fabb3df77cc2d77782c
parent5c684a003a
authorLucas Galante <lsgalante12@gmail.com>
date2026-09-25 10:48
feat: the viewport menu's point overlays get a group of their own

Points keeps Show Points, Point Size and the Group Marker Scale that
multiplies it; a new overlays group behind its own separator holds Show
Point Markers and its size, Show Point Numbers and Show Point Normals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 CLAUDE.md   | 13 ++++++-------
 src/app.rs  | 24 +++++++++++++-----------
 src/main.rs | 16 +++++++++-------
 3 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index ab36e5d..7841c94 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1377,13 +1377,12 @@ multi-selection, so taking `Shift+L` now would have to be given back later.
 ### Display mode: the viewport menu, and smooth shading
 
 The viewport's right-click menu carries the DISPLAY MODE under Frame All
-and View 1:1, in three groups a separator apart — wireframe (switch,
-thickness), points (Show Points and Point Size, Show Point Markers and
-its size, Show Point Numbers, Show Point Normals, Group Marker Scale —
-each switch over its
-own size where it has one), surface
-(shading, opacity,
-Show Occluded); `the_viewport_menu_groups_its_display_rows` holds the
+and View 1:1, in four groups a separator apart — wireframe (switch,
+thickness); points (Show Points, Point Size, and Group Marker Scale, which
+multiplies it); overlays (Show Point Markers and its size, Show Point
+Numbers, Show Point Normals — the annotations over the scene's points);
+surface (shading, opacity, Show Occluded).
+`the_viewport_menu_groups_its_display_rows` holds the
 order. The rows: the Show Wireframe switch (its registry command), **Flat
 Shading / Smooth Shading** as a radio pair over `toggle_smooth_shading`,
 a **Wire Thickness** slider under the wireframe switch (1–8 px by
diff --git a/src/app.rs b/src/app.rs
index d3ac1fa..4acf6c4 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -4463,15 +4463,14 @@ impl State {
 
     /// The viewport menu's rows and what each does, in groups a separator
     /// apart: framing; the WIREFRAME (its switch and thickness); the POINTS
-    /// (the Show Points switch and point size, the Show Point Markers switch
-    /// and its size, the Show Point Numbers and Show Point Normals
-    /// switches, group marker scale —
-    /// each switch over its own size, where it has one);
-    /// the SURFACE
-    /// (flat or smooth shading as a radio pair, the polygon opacity, Show
-    /// Occluded — the three that decide how the fill itself reads); then
-    /// the editor pin. Split from the open so a test can read it. Marks are
-    /// the ●/○ the pin rows and the network menu use.
+    /// (the Show Points switch, point size, and the group marker scale that
+    /// multiplies it); the OVERLAYS (Show Point Markers and its size, Show
+    /// Point Numbers, Show Point Normals — the annotations drawn over the
+    /// scene's points); the SURFACE (flat or smooth shading as a radio pair,
+    /// the polygon opacity, Show Occluded — the three that decide how the
+    /// fill itself reads); then the editor pin. Split from the open so a
+    /// test can read it. Marks are the ●/○ the pin rows and the network menu
+    /// use.
     pub(crate) fn viewport_menu_rows(&self) -> (Vec<String>, Vec<ViewportMenuAction>) {
         let mut options = vec!["Frame All".to_string(), "View 1:1".to_string()];
         let mut actions = vec![ViewportMenuAction::FrameAll, ViewportMenuAction::OneToOne];
@@ -4488,15 +4487,18 @@ impl State {
         row(&mut options, &mut actions, format!("{} {}", mark(self.wireframe), label("toggle_wireframe", "Show Wireframe")), ViewportMenuAction::Command("toggle_wireframe"));
         row(&mut options, &mut actions, "Wire Thickness".into(), ViewportMenuAction::WireThicknessSlider);
 
-        // Points.
+        // Points: the Render points, and the group markers sized off them.
         row(&mut options, &mut actions, "-".into(), sep);
         row(&mut options, &mut actions, format!("{} {}", mark(self.render_points), label("toggle_render_points", "Show Points")), ViewportMenuAction::Command("toggle_render_points"));
         row(&mut options, &mut actions, "Point Size".into(), ViewportMenuAction::PointSizeSlider);
+        row(&mut options, &mut actions, "Group Marker Scale".into(), ViewportMenuAction::GroupMarkerScaleSlider);
+
+        // Overlays: the three annotations over the scene's points.
+        row(&mut options, &mut actions, "-".into(), sep);
         row(&mut options, &mut actions, format!("{} {}", mark(self.show_point_markers), label("toggle_point_markers", "Show Point Markers")), ViewportMenuAction::Command("toggle_point_markers"));
         row(&mut options, &mut actions, "Point Marker Size".into(), ViewportMenuAction::PointMarkerSizeSlider);
         row(&mut options, &mut actions, format!("{} {}", mark(self.show_point_numbers), label("toggle_point_numbers", "Show Point Numbers")), ViewportMenuAction::Command("toggle_point_numbers"));
         row(&mut options, &mut actions, format!("{} {}", mark(self.show_point_normals), label("toggle_point_normals", "Show Point Normals")), ViewportMenuAction::Command("toggle_point_normals"));
-        row(&mut options, &mut actions, "Group Marker Scale".into(), ViewportMenuAction::GroupMarkerScaleSlider);
 
         // Surface.
         row(&mut options, &mut actions, "-".into(), sep);
diff --git a/src/main.rs b/src/main.rs
index ce89240..c1c7600 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1645,8 +1645,9 @@ mod tests {
     }
 
     /// The viewport menu reads in groups a separator apart: framing, then
-    /// the wireframe, the points, and the surface (shading, opacity, Show
-    /// Occluded) — every display row in exactly one group.
+    /// the wireframe, the points, the point overlays, and the surface
+    /// (shading, opacity, Show Occluded) — every display row in exactly one
+    /// group.
     #[test]
     fn the_viewport_menu_groups_its_display_rows() {
         use crate::app::ViewportMenuAction as A;
@@ -1660,18 +1661,19 @@ mod tests {
         assert_eq!(groups[1], vec![A::Command("toggle_wireframe"), A::WireThicknessSlider]);
         assert_eq!(
             groups[2],
+            vec![A::Command("toggle_render_points"), A::PointSizeSlider, A::GroupMarkerScaleSlider]
+        );
+        assert_eq!(
+            groups[3],
             vec![
-                A::Command("toggle_render_points"),
-                A::PointSizeSlider,
                 A::Command("toggle_point_markers"),
                 A::PointMarkerSizeSlider,
                 A::Command("toggle_point_numbers"),
                 A::Command("toggle_point_normals"),
-                A::GroupMarkerScaleSlider,
             ]
         );
         assert_eq!(
-            groups[3],
+            groups[4],
             vec![A::Shading(false), A::Shading(true), A::OpacitySlider, A::Command("toggle_show_occluded")]
         );
         assert_eq!(options.len(), actions.len());
@@ -1931,7 +1933,7 @@ mod tests {
         state.cursor_y = 200.0;
         state.open_viewport_context_menu();
         let i = state.viewport_menu_actions.iter().position(|a| *a == A::GroupMarkerScaleSlider).expect("a Group Marker Scale row");
-        assert_eq!(state.viewport_menu_actions[i - 1], A::Command("toggle_point_normals"));
+        assert_eq!(state.viewport_menu_actions[i - 1], A::PointSizeSlider, "it sits under the size it multiplies");
         let sl = context_menu::slider(i).expect("a slider");
         assert_eq!((sl.min, sl.max, sl.step, sl.suffix), (0.5, 4.0, 0.05, "x"));
         assert_eq!(sl.readout(), "1.25x");