From 8bdf5228d2e9716a720d7f953c51908862899a7d Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Sat, 27 Jun 2026 01:56:17 +0300 Subject: [PATCH] refactor(viewcube): shrink cube 30%, compact controls, centre UCS picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce the ViewCube 30% (VIEWCUBE_PX 120→84) and tighten the nav region (NAV_INSET_F 2.2→2.0) so the home / roll / nudge controls hug the cube in the corner instead of floating in a large dead area, with sizes scaled to keep them from overlapping. Bump the home and roll buttons back up slightly, shift the UCS picker down below the region, and give it a fixed width so it centres exactly under the cube centre. Co-Authored-By: Claude Opus 4.8 --- src/app/view/mod.rs | 10 +++++----- src/app/view/viewcube.rs | 26 ++++++++++++++++---------- src/scene/pipeline/viewcube.rs | 7 ++++--- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/app/view/mod.rs b/src/app/view/mod.rs index 7be801a8b..73022584d 100644 --- a/src/app/view/mod.rs +++ b/src/app/view/mod.rs @@ -23,7 +23,7 @@ use overlay::{ layout_context_menu_overlay, mtext_editor_overlay, position_canvas_overlay, qselect_overlay, text_inline_overlay, viewport_context_menu_overlay, }; -use viewcube::{viewcube_nav_controls, viewcube_ucs_picker}; +use viewcube::{viewcube_nav_controls, viewcube_ucs_picker, UCS_PICKER_W}; // Re-export the text-input element ids so sibling modules can address them at // the `view::` path as before the split. @@ -587,10 +587,10 @@ impl OpenCADStudio { .filter(|n| !n.is_empty()) .collect(); let picker = column![ - Space::new().height(iced::Length::Fixed(cube_y + VIEWCUBE_HIT_SIZE - 8.0)), + Space::new().height(iced::Length::Fixed(cube_y + VIEWCUBE_HIT_SIZE + 6.0)), row![ Space::new() - .width(iced::Length::Fixed(cube_x + VIEWCUBE_HIT_SIZE * 0.5 - 42.0)), + .width(iced::Length::Fixed(cube_x + VIEWCUBE_HIT_SIZE * 0.5 - UCS_PICKER_W * 0.5)), iced::widget::opaque(viewcube_ucs_picker(ucs_current, ucs_names)), ], ] @@ -636,9 +636,9 @@ impl OpenCADStudio { .filter(|n| !n.is_empty()) .collect(); let picker = column![ - Space::new().height(iced::Length::Fixed(cube_y + VIEWCUBE_HIT_SIZE - 8.0)), + Space::new().height(iced::Length::Fixed(cube_y + VIEWCUBE_HIT_SIZE + 6.0)), row![ - Space::new().width(iced::Length::Fixed(cube_x + VIEWCUBE_HIT_SIZE * 0.5 - 42.0)), + Space::new().width(iced::Length::Fixed(cube_x + VIEWCUBE_HIT_SIZE * 0.5 - UCS_PICKER_W * 0.5)), iced::widget::opaque(viewcube_ucs_picker(ucs_current, ucs_names)), ], ] diff --git a/src/app/view/viewcube.rs b/src/app/view/viewcube.rs index 39e1a0bf5..495519fd5 100644 --- a/src/app/view/viewcube.rs +++ b/src/app/view/viewcube.rs @@ -70,9 +70,9 @@ pub(super) fn viewcube_nav_controls<'a>() -> Element<'a, Message> { let r = VIEWCUBE_REGION_PX; let c = r * 0.5; let cube_half = VIEWCUBE_PX as f32 * 0.36; // VIEWCUBE_PX * VIEWCUBE_SCALE - let nr = cube_half + 8.0; // nudge triangle distance from centre - const BTN: f32 = 18.0; - const TRI: f32 = 13.0; + let nr = cube_half + 6.0; // nudge triangle distance from centre + const BTN: f32 = 16.0; + const TRI: f32 = 9.0; let ctr = |cx: f32, cy: f32, s: f32| (cx - s * 0.5, cy - s * 0.5); // Home top-left, roll arrows top-right. @@ -101,23 +101,23 @@ pub(super) fn viewcube_nav_controls<'a>() -> Element<'a, Message> { vc_place( 3.0, 3.0, - vc_btn(icons::home(15.0, tint), BTN, Message::ViewCubeHome) + vc_btn(icons::home(13.0, tint), BTN, Message::ViewCubeHome) ), vc_place( rax, ray, - vc_btn(icons::undo(14.0, tint), BTN, Message::ViewCubeRoll(false)) + vc_btn(icons::undo(12.0, tint), BTN, Message::ViewCubeRoll(false)) ), vc_place( rbx, rby, - vc_btn(icons::redo(14.0, tint), BTN, Message::ViewCubeRoll(true)) + vc_btn(icons::redo(12.0, tint), BTN, Message::ViewCubeRoll(true)) ), vc_place( tux, tuy, vc_btn( - icons::arrow_down(11.0, tint), + icons::arrow_down(8.0, tint), TRI, Message::ViewCubeNudge(NudgeDir::Up) ) @@ -126,7 +126,7 @@ pub(super) fn viewcube_nav_controls<'a>() -> Element<'a, Message> { tdx, tdy, vc_btn( - icons::arrow_up(11.0, tint), + icons::arrow_up(8.0, tint), TRI, Message::ViewCubeNudge(NudgeDir::Down) ) @@ -135,7 +135,7 @@ pub(super) fn viewcube_nav_controls<'a>() -> Element<'a, Message> { tlx, tly, vc_btn( - icons::arrow_right(11.0, tint), + icons::arrow_right(8.0, tint), TRI, Message::ViewCubeNudge(NudgeDir::Left) ) @@ -144,7 +144,7 @@ pub(super) fn viewcube_nav_controls<'a>() -> Element<'a, Message> { trx, try_, vc_btn( - icons::arrow_left(11.0, tint), + icons::arrow_left(8.0, tint), TRI, Message::ViewCubeNudge(NudgeDir::Right) ) @@ -157,6 +157,9 @@ pub(super) fn viewcube_nav_controls<'a>() -> Element<'a, Message> { .into() } +/// Fixed width of the UCS picker, so it can be centred under the cube. +pub(super) const UCS_PICKER_W: f32 = 84.0; + /// The WCS / named-UCS selector shown under the cube. pub(super) fn viewcube_ucs_picker<'a>(current: String, names: Vec) -> Element<'a, Message> { let light = Color { @@ -175,6 +178,9 @@ pub(super) fn viewcube_ucs_picker<'a>(current: String, names: Vec) -> El pick_list(options, Some(selected), Message::SetViewcubeUcs) .text_size(11) .padding([2, 6]) + // Fixed width so the caller can centre it under the cube centre with a + // simple half-width offset (content-sized width would drift off-centre). + .width(iced::Length::Fixed(UCS_PICKER_W)) .style(move |_: &Theme, _| iced::widget::pick_list::Style { background: Background::Color(Color { r: 0.16, diff --git a/src/scene/pipeline/viewcube.rs b/src/scene/pipeline/viewcube.rs index 2f5b83164..e9868a215 100644 --- a/src/scene/pipeline/viewcube.rs +++ b/src/scene/pipeline/viewcube.rs @@ -15,14 +15,15 @@ use iced::wgpu; use iced::{Rectangle, Size}; // ── ViewCube layout ─────────────────────────────────────────────────────── -pub const VIEWCUBE_PX: u32 = 120; +pub const VIEWCUBE_PX: u32 = 84; // 30% smaller cube (was 120) pub const VIEWCUBE_SCALE: f32 = 0.36; pub const VIEWCUBE_DRAW_PX: f32 = VIEWCUBE_PX as f32 * VIEWCUBE_SCALE * 2.0; pub const VIEWCUBE_PAD: f32 = 12.0; /// The cube centre is inset from the screen corner by this multiple of the /// cube half-size, leaving room for the compass ring and the nav controls -/// (home / roll / nudge) drawn around it. -pub const NAV_INSET_F: f32 = 2.2; +/// (home / roll / nudge) drawn around it. Tighter than before so the controls +/// hug the cube in the corner instead of floating in a large dead region. +pub const NAV_INSET_F: f32 = 2.0; /// Side of the whole nav widget (cube + compass ring + controls) in pixels. pub const VIEWCUBE_REGION_PX: f32 = VIEWCUBE_DRAW_PX * NAV_INSET_F; /// Z height of the compass ring + cardinals in cube-local space. The cube