graphic design tool
git clone https://git.lucas.co/cce-designer.git
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");