diff --git a/src/app/commands.rs b/src/app/commands.rs index b5d720431..6310bc89d 100644 --- a/src/app/commands.rs +++ b/src/app/commands.rs @@ -3700,6 +3700,20 @@ impl H7CAD { "UCSICON {sub}: updated {count} viewport(s) + model space." )); } + "" => { + // Bare UCSICON toggles visibility. + self.push_undo_snapshot(i, "UCSICON"); + let visible = !self.show_ucs_icon; + self.show_ucs_icon = visible; + for entity in self.tabs[i].scene.document.entities_mut() { + if let acadrust::EntityType::Viewport(vp) = entity { + vp.status.ucs_icon_visible = visible; + } + } + self.tabs[i].dirty = true; + let state = if visible { "ON" } else { "OFF" }; + self.command_line.push_output(&format!("UCSICON {state}")); + } _ => { self.command_line.push_info("Usage: UCSICON ON | OFF | NOORIGIN | ORIGIN"); } diff --git a/src/app/view.rs b/src/app/view.rs index 9001af89d..643a05fdc 100644 --- a/src/app/view.rs +++ b/src/app/view.rs @@ -108,7 +108,7 @@ impl H7CAD { let viewport_3d: Element<'_, Message> = if is_paper { paper_canvas_view(tab) } else { - shader(ViewportPane::model(&tab.scene)) + shader(ViewportPane::model(&tab.scene, self.show_viewcube)) .width(Fill) .height(Fill) .into() diff --git a/src/scene/render.rs b/src/scene/render.rs index 56c6bce90..3e6c4d4bf 100644 --- a/src/scene/render.rs +++ b/src/scene/render.rs @@ -88,6 +88,7 @@ pub struct Primitive { pub(super) hover_region: Option, /// Background color used to clear the MSAA buffer at the start of each frame. pub(super) bg_color: [f32; 4], + pub(super) show_viewcube: bool, } // ── shader::Primitive impl ──────────────────────────────────────────────── @@ -120,13 +121,15 @@ impl shader::Primitive for Primitive { pipeline.upload_images(device, queue, &self.images); pipeline.upload_meshes(device, &self.meshes); pipeline.upload_wires(device, &self.wires); - pipeline.viewcube.upload( - queue, - self.cam_rotation, - bounds.width as u32, - bounds.height as u32, - self.hover_region, - ); + if self.show_viewcube { + pipeline.viewcube.upload( + queue, + self.cam_rotation, + bounds.width as u32, + bounds.height as u32, + self.hover_region, + ); + } } fn render( @@ -137,7 +140,9 @@ impl shader::Primitive for Primitive { clip: &Rectangle, ) { pipeline.render(encoder, target, *clip, self.bg_color); - pipeline.viewcube.render(encoder, target, *clip); + if self.show_viewcube { + pipeline.viewcube.render(encoder, target, *clip); + } } } @@ -216,6 +221,7 @@ impl Scene { &self, hover_region: Option, bounds: Rectangle, + show_viewcube: bool, ) -> Primitive { let cam = self.camera.borrow(); self.selection.borrow_mut().vp_size = (bounds.width, bounds.height); @@ -242,6 +248,7 @@ impl Scene { cam_rotation: cam.view_rotation_mat(), hover_region, bg_color, + show_viewcube, } } @@ -256,7 +263,7 @@ impl Scene { ) -> Primitive { let cam = match self.camera_for_viewport(vp_handle) { Some(c) => c, - None => return self.build_primitive(hover_region, bounds), + None => return self.build_primitive(hover_region, bounds, false), }; let mut all_wires = self.model_wires_for_viewport(vp_handle); @@ -275,6 +282,7 @@ impl Scene { cam_rotation: cam.view_rotation_mat(), hover_region, bg_color: self.bg_color, + show_viewcube: false, } } diff --git a/src/scene/viewport_pane.rs b/src/scene/viewport_pane.rs index af50f44aa..1784ec108 100644 --- a/src/scene/viewport_pane.rs +++ b/src/scene/viewport_pane.rs @@ -25,18 +25,19 @@ pub enum ViewportPaneMode { pub struct ViewportPane<'a> { pub scene: &'a Scene, pub mode: ViewportPaneMode, + pub show_viewcube: bool, } impl<'a> ViewportPane<'a> { - pub fn model(scene: &'a Scene) -> Self { - Self { scene, mode: ViewportPaneMode::Model } + pub fn model(scene: &'a Scene, show_viewcube: bool) -> Self { + Self { scene, mode: ViewportPaneMode::Model, show_viewcube } } /// One paper-space viewport: model content rendered through its own camera. /// See [`ViewportPaneMode::Paper`] for why this is currently unused. #[allow(dead_code)] pub fn paper(scene: &'a Scene, handle: Handle) -> Self { - Self { scene, mode: ViewportPaneMode::Paper { handle } } + Self { scene, mode: ViewportPaneMode::Paper { handle }, show_viewcube: false } } } @@ -106,7 +107,7 @@ impl<'a, Msg: std::fmt::Debug + Clone> shader::Program for ViewportPane<'a> ) -> Self::Primitive { match &self.mode { ViewportPaneMode::Model => { - self.scene.build_primitive(state.hover_region, bounds) + self.scene.build_primitive(state.hover_region, bounds, self.show_viewcube) } ViewportPaneMode::Paper { handle } => { self.scene.build_viewport_primitive(*handle, state.hover_region, bounds) @@ -122,8 +123,10 @@ impl<'a, Msg: std::fmt::Debug + Clone> shader::Program for ViewportPane<'a> cursor: mouse::Cursor, ) -> Option> { // ViewCube hover only makes sense in the full model-space view. - if matches!(self.mode, ViewportPaneMode::Model) { + if matches!(self.mode, ViewportPaneMode::Model) && self.show_viewcube { self.scene.update_viewcube_state(state, bounds, cursor); + } else { + state.hover_region = None; } let _ = event; None @@ -135,7 +138,7 @@ impl<'a, Msg: std::fmt::Debug + Clone> shader::Program for ViewportPane<'a> _b: Rectangle, _c: mouse::Cursor, ) -> mouse::Interaction { - if matches!(self.mode, ViewportPaneMode::Model) { + if matches!(self.mode, ViewportPaneMode::Model) && self.show_viewcube { self.scene.viewcube_mouse_interaction(state) } else { mouse::Interaction::default()