forked from 1b-agent/opencadstudio-upstream
feat: introduce ViewportPane widget for unified model/paper rendering
- Remove Scene: shader::Program<Msg> impl; all GPU rendering now goes
through ViewportPane which supports three modes:
Model — full model-space view (unchanged behaviour)
PaperSheet — paper-space entities only, using the paper camera
Paper — model content through a specific viewport's own camera
- Add Scene helper methods (render.rs):
build_primitive / build_paper_sheet_primitive / build_viewport_primitive
update_viewcube_state / viewcube_mouse_interaction
- Add Scene helpers (mod.rs):
paper_sheet_wires() — paper entities without viewport projection
camera_for_viewport() — derive Camera from Viewport entity data
model_wires_for_viewport() — model wires filtered by per-viewport frozen layers
viewport_screen_rect() — paper-space → pixel rect mapping
- Add paper_canvas_view() in view.rs:
Stack of PaperSheet + one Paper widget per Viewport entity,
positioned with Space offsets from viewport_screen_rect()
- Update VIEWPORT_WIDGET_PLAN.md: mark Steps 1–4 done, document remaining work
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
de04b7e351
commit
da9fafc0f8
5 files changed
+594
-81
No files matched your search
@@ -0,0 +1,94 @@
|
||||
use super::render::{CameraState, Primitive};
|
||||
use super::Scene;
|
||||
use acadrust::Handle;
|
||||
use iced::widget::shader;
|
||||
use iced::{mouse, Event, Rectangle};
|
||||
|
||||
// ── Mode ──────────────────────────────────────────────────────────────────
|
||||
|
||||
pub enum ViewportPaneMode {
|
||||
/// Full model space — fills whatever bounds Iced assigns.
|
||||
Model,
|
||||
/// Paper-space entities only (title blocks, frames, borders) using the
|
||||
/// paper-space camera. No viewport content projection.
|
||||
PaperSheet,
|
||||
/// Model-space content seen through a specific paper-space Viewport entity.
|
||||
Paper { handle: Handle },
|
||||
}
|
||||
|
||||
// ── Widget struct ─────────────────────────────────────────────────────────
|
||||
|
||||
pub struct ViewportPane<'a> {
|
||||
pub scene: &'a Scene,
|
||||
pub mode: ViewportPaneMode,
|
||||
}
|
||||
|
||||
impl<'a> ViewportPane<'a> {
|
||||
pub fn model(scene: &'a Scene) -> Self {
|
||||
Self { scene, mode: ViewportPaneMode::Model }
|
||||
}
|
||||
|
||||
/// Paper-sheet layer: paper-space entities rendered with the paper camera.
|
||||
pub fn paper_sheet(scene: &'a Scene) -> Self {
|
||||
Self { scene, mode: ViewportPaneMode::PaperSheet }
|
||||
}
|
||||
|
||||
/// One paper-space viewport: model content rendered through its own camera.
|
||||
pub fn paper(scene: &'a Scene, handle: Handle) -> Self {
|
||||
Self { scene, mode: ViewportPaneMode::Paper { handle } }
|
||||
}
|
||||
}
|
||||
|
||||
// ── shader::Program impl ──────────────────────────────────────────────────
|
||||
|
||||
impl<'a, Msg: std::fmt::Debug + Clone> shader::Program<Msg> for ViewportPane<'a> {
|
||||
type State = CameraState;
|
||||
type Primitive = Primitive;
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
_cursor: mouse::Cursor,
|
||||
bounds: Rectangle,
|
||||
) -> Self::Primitive {
|
||||
match &self.mode {
|
||||
ViewportPaneMode::Model => {
|
||||
self.scene.build_primitive(state.hover_region, bounds)
|
||||
}
|
||||
ViewportPaneMode::PaperSheet => {
|
||||
self.scene.build_paper_sheet_primitive(state.hover_region, bounds)
|
||||
}
|
||||
ViewportPaneMode::Paper { handle } => {
|
||||
self.scene.build_viewport_primitive(*handle, state.hover_region, bounds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update(
|
||||
&self,
|
||||
state: &mut Self::State,
|
||||
event: &Event,
|
||||
bounds: Rectangle,
|
||||
cursor: mouse::Cursor,
|
||||
) -> Option<iced::widget::Action<Msg>> {
|
||||
// ViewCube hover only makes sense in the full model-space view.
|
||||
if matches!(self.mode, ViewportPaneMode::Model | ViewportPaneMode::PaperSheet) {
|
||||
self.scene.update_viewcube_state(state, bounds, cursor);
|
||||
}
|
||||
let _ = event;
|
||||
None
|
||||
}
|
||||
|
||||
fn mouse_interaction(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
_b: Rectangle,
|
||||
_c: mouse::Cursor,
|
||||
) -> mouse::Interaction {
|
||||
if matches!(self.mode, ViewportPaneMode::Model | ViewportPaneMode::PaperSheet) {
|
||||
self.scene.viewcube_mouse_interaction(state)
|
||||
} else {
|
||||
mouse::Interaction::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user