forked from 1b-agent/opencadstudio-upstream
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
2baabdf4a0
commit
bddc050b3e
39 files changed
+26674
-26113
No files matched your search
@@ -0,0 +1,195 @@
|
||||
use super::super::Message;
|
||||
use crate::scene::{VIEWCUBE_PX, VIEWCUBE_REGION_PX};
|
||||
use iced::widget::{
|
||||
button, column, container, mouse_area, pick_list, row, stack,
|
||||
Space,
|
||||
};
|
||||
use iced::{Background, Border, Color, Element, Fill, Theme};
|
||||
|
||||
// ── Render-mode picker ──────────────────────────────────────────────────────
|
||||
|
||||
/// Top-left viewport control bar: a single dark chip holding (optionally) the
|
||||
/// horizontal/vertical split buttons, the render-mode picker, and the grid /
|
||||
/// grid-snap toggles. `include_split` is off for paper-space viewports, which
|
||||
/// have no model-tile splitting. Grid / snap reflect the active viewport's
|
||||
/// state and emit `ToggleGrid` / `ToggleGridSnap`.
|
||||
// ── ViewCube navigation controls (home / roll / nudge / UCS) ───────────────
|
||||
|
||||
/// Place `el` at pixel offset (x, y) inside a Fill layer (top-left origin).
|
||||
fn vc_place<'a>(x: f32, y: f32, el: Element<'a, Message>) -> Element<'a, Message> {
|
||||
column![
|
||||
Space::new().height(iced::Length::Fixed(y.max(0.0))),
|
||||
row![Space::new().width(iced::Length::Fixed(x.max(0.0))), el],
|
||||
]
|
||||
.width(Fill)
|
||||
.height(Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Borderless square icon button used by the ViewCube nav controls.
|
||||
fn vc_btn<'a>(content: Element<'a, Message>, size: f32, msg: Message) -> Element<'a, Message> {
|
||||
button(
|
||||
container(content)
|
||||
.width(iced::Length::Fixed(size))
|
||||
.height(iced::Length::Fixed(size))
|
||||
.center_x(iced::Length::Fixed(size))
|
||||
.center_y(iced::Length::Fixed(size)),
|
||||
)
|
||||
.padding(0)
|
||||
.on_press(msg)
|
||||
.style(|_: &Theme, status| iced::widget::button::Style {
|
||||
background: Some(Background::Color(match status {
|
||||
iced::widget::button::Status::Hovered | iced::widget::button::Status::Pressed => Color {
|
||||
r: 0.45,
|
||||
g: 0.62,
|
||||
b: 0.95,
|
||||
a: 0.30,
|
||||
},
|
||||
_ => Color::TRANSPARENT,
|
||||
})),
|
||||
border: Border {
|
||||
radius: 3.0.into(),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Overlay of home / roll / nudge controls sized to the whole nav region, so
|
||||
/// the caller can position it exactly like the cube hit area.
|
||||
pub(super) fn viewcube_nav_controls<'a>() -> Element<'a, Message> {
|
||||
use crate::scene::NudgeDir;
|
||||
use crate::ui::icons;
|
||||
let tint = Color {
|
||||
r: 0.86,
|
||||
g: 0.89,
|
||||
b: 0.96,
|
||||
a: 1.0,
|
||||
};
|
||||
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 ctr = |cx: f32, cy: f32, s: f32| (cx - s * 0.5, cy - s * 0.5);
|
||||
|
||||
// Home top-left, roll arrows top-right.
|
||||
let (rax, ray) = (r - 2.0 * BTN - 4.0, 2.0);
|
||||
let (rbx, rby) = (r - BTN - 2.0, 2.0);
|
||||
// Nudge triangles pointing inward at the four cube faces.
|
||||
let (tux, tuy) = ctr(c, c - nr, TRI);
|
||||
let (tdx, tdy) = ctr(c, c + nr, TRI);
|
||||
let (tlx, tly) = ctr(c - nr, c, TRI);
|
||||
let (trx, try_) = ctr(c + nr, c, TRI);
|
||||
|
||||
// Bottom layer: the cube/cardinal hit area covering the whole region. The
|
||||
// control buttons sit ABOVE it in the same stack, so a click on a button is
|
||||
// caught by the button while a click on the cube (or empty space) falls
|
||||
// through to this mouse_area → ViewportClick. Moves keep cursor_pos current.
|
||||
let cube_hit = mouse_area(
|
||||
Space::new()
|
||||
.width(iced::Length::Fixed(r))
|
||||
.height(iced::Length::Fixed(r)),
|
||||
)
|
||||
.on_move(Message::CursorMoved)
|
||||
.on_press(Message::ViewportClick);
|
||||
|
||||
let controls = stack![
|
||||
cube_hit,
|
||||
vc_place(
|
||||
3.0,
|
||||
3.0,
|
||||
vc_btn(icons::home(15.0, tint), BTN, Message::ViewCubeHome)
|
||||
),
|
||||
vc_place(
|
||||
rax,
|
||||
ray,
|
||||
vc_btn(icons::undo(14.0, tint), BTN, Message::ViewCubeRoll(false))
|
||||
),
|
||||
vc_place(
|
||||
rbx,
|
||||
rby,
|
||||
vc_btn(icons::redo(14.0, tint), BTN, Message::ViewCubeRoll(true))
|
||||
),
|
||||
vc_place(
|
||||
tux,
|
||||
tuy,
|
||||
vc_btn(
|
||||
icons::arrow_down(11.0, tint),
|
||||
TRI,
|
||||
Message::ViewCubeNudge(NudgeDir::Up)
|
||||
)
|
||||
),
|
||||
vc_place(
|
||||
tdx,
|
||||
tdy,
|
||||
vc_btn(
|
||||
icons::arrow_up(11.0, tint),
|
||||
TRI,
|
||||
Message::ViewCubeNudge(NudgeDir::Down)
|
||||
)
|
||||
),
|
||||
vc_place(
|
||||
tlx,
|
||||
tly,
|
||||
vc_btn(
|
||||
icons::arrow_right(11.0, tint),
|
||||
TRI,
|
||||
Message::ViewCubeNudge(NudgeDir::Left)
|
||||
)
|
||||
),
|
||||
vc_place(
|
||||
trx,
|
||||
try_,
|
||||
vc_btn(
|
||||
icons::arrow_left(11.0, tint),
|
||||
TRI,
|
||||
Message::ViewCubeNudge(NudgeDir::Right)
|
||||
)
|
||||
),
|
||||
];
|
||||
|
||||
container(controls)
|
||||
.width(iced::Length::Fixed(r))
|
||||
.height(iced::Length::Fixed(r))
|
||||
.into()
|
||||
}
|
||||
|
||||
/// The WCS / named-UCS selector shown under the cube.
|
||||
pub(super) fn viewcube_ucs_picker<'a>(current: String, names: Vec<String>) -> Element<'a, Message> {
|
||||
let light = Color {
|
||||
r: 0.85,
|
||||
g: 0.87,
|
||||
b: 0.93,
|
||||
a: 1.0,
|
||||
};
|
||||
let mut options = vec!["WCS".to_string()];
|
||||
options.extend(names);
|
||||
let selected = if current.is_empty() {
|
||||
"WCS".to_string()
|
||||
} else {
|
||||
current
|
||||
};
|
||||
pick_list(options, Some(selected), Message::SetViewcubeUcs)
|
||||
.text_size(11)
|
||||
.padding([2, 6])
|
||||
.style(move |_: &Theme, _| iced::widget::pick_list::Style {
|
||||
background: Background::Color(Color {
|
||||
r: 0.16,
|
||||
g: 0.17,
|
||||
b: 0.20,
|
||||
a: 0.92,
|
||||
}),
|
||||
border: Border {
|
||||
radius: 3.0.into(),
|
||||
..Default::default()
|
||||
},
|
||||
text_color: light,
|
||||
placeholder_color: light,
|
||||
handle_color: light,
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user