feat: replace paper-space shader with 2D Iced canvas widget

Paper space is now rendered as a 2D vector canvas (iced::widget::canvas)
instead of a 3D shader widget.  This allows direct interaction with
paper-space entities (title blocks, viewport borders, annotations)
without needing to enter MSPACE first.

Changes:
- src/scene/paper_canvas.rs: new PaperCanvas<'a> canvas::Program that
  renders paper wires (with linetype dashes), solid/gradient hatch fills,
  and wipeout backgrounds using the paper camera's orthographic transform.
- Scene: three new public helpers (paper_canvas_wires, paper_canvas_hatches,
  paper_canvas_wipeouts) feed the canvas with the same data the old shader
  used, including inactive viewport projections and interim/preview wires.
- view.rs: paper_canvas_view() now wraps PaperCanvas instead of
  shader(ViewportPane::paper_sheet(…)).  The PaperViewportPane 3D shader
  overlay for the active MSPACE viewport is unchanged.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Sonnet 4.6 committed 2026-04-23 09:48:53 +03:00
1 parent 1c0520e4e4
commit 459b525ffe
3 files changed
+224 -2

No files matched your search

+25
View File
@@ -10,6 +10,7 @@ pub mod hit_test;
pub mod image_model;
pub mod mesh_model;
pub mod object;
pub mod paper_canvas;
pub mod pipeline;
pub mod properties;
mod render;
@@ -2214,6 +2215,30 @@ impl Scene {
/// Paper-space entity wires only (title blocks, frames, borders).
/// Does NOT include viewport content projection — that is handled by
/// individual ViewportPane::Paper widgets layered on top.
/// All wires needed to render the paper-space canvas (2D widget path).
/// Includes paper entities, paper boundary, inactive viewport projections
/// (excluding the active MSPACE viewport), plus interim/preview wires.
pub fn paper_canvas_wires(&self) -> Vec<WireModel> {
let layout_block = self.current_layout_block_handle();
let mut wires = self.paper_sheet_wires();
wires.extend(self.viewport_content_wires(layout_block, None, self.active_viewport));
if let Some(iw) = &self.interim_wire {
wires.push(iw.clone());
}
wires.extend(self.preview_wires.iter().cloned());
wires
}
/// Hatch fills for the paper-space canvas.
pub fn paper_canvas_hatches(&self) -> Vec<HatchModel> {
self.synced_hatch_models()
}
/// Wipeout (opaque background fill) models for the paper-space canvas.
pub fn paper_canvas_wipeouts(&self) -> Vec<HatchModel> {
self.wipeout_models()
}
pub(super) fn paper_sheet_wires(&self) -> Vec<WireModel> {
let layout_block = self.current_layout_block_handle();
let mut wires = self.wires_for_block(layout_block);