forked from 1b-agent/opencadstudio-upstream
refactor(viewport): migrate model-space tiling to iced pane_grid
Replace the custom model_tiles tiling with iced 0.14 pane_grid as the layout source of truth, while paper-space floating viewports are left untouched (they overlap/free-place, which pane_grid cannot model). Each Model pane is its own shader widget rendering its camera into the pane bounds; the renderer Primitive carries a base_slot so several shader widgets share the type-keyed MultiPipeline storage on disjoint slots. A second pane_grid of transparent mouse_areas (plus on_resize) layers above the crosshair overlay to receive input — the overlay's Hidden cursor interaction otherwise levitates the cursor and starves any layer beneath it. The active pane follows the cursor (hover-activate), and grid / crosshair / UCS icon render per pane while the ViewCube and render-mode picker stay on the active pane only. Split / close / VPORTS presets and the VPort table round-trip now drive pane_grid (guillotine reconstruction on load). Adds drag-to-swap via a controls bar handle with a ghost-card preview, visible pane dividers from the pane_grid split regions, a default model background of RGB(33,40,48), and removes all the superseded custom-tile code. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
8bdf5228d2
commit
495b13ec4f
18 files changed
+1022
-751
No files matched your search
+14
-21
@@ -527,27 +527,10 @@ pub(crate) struct ModelTile {
|
||||
pub(crate) snap_on: bool,
|
||||
}
|
||||
|
||||
/// Tolerance for matching two normalized tile coordinates as "the same"
|
||||
/// edge — drag math leaves small floating-point residue.
|
||||
const TILE_EPS: f32 = 1e-4;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum TileEdgeOrient {
|
||||
Vertical,
|
||||
Horizontal,
|
||||
}
|
||||
|
||||
/// One inner divider between Model tiles, exposed by [`Scene::model_tile_edges`].
|
||||
/// `coord` is the fixed axis (x for vertical, y for horizontal) and `span`
|
||||
/// is the perpendicular extent over which the divider actually separates
|
||||
/// tiles. All values are normalized to the 0..1 canvas.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TileEdge {
|
||||
pub orient: TileEdgeOrient,
|
||||
pub coord: f32,
|
||||
pub span: (f32, f32),
|
||||
}
|
||||
|
||||
/// Gap (pixels) between Model panes — the `pane_grid` spacing and the visible
|
||||
/// divider width. The renderer derives tile rects through this same spacing so
|
||||
/// the drawn viewports line up exactly with the pane_grid layout.
|
||||
pub const TILE_DIVIDER_PX: f32 = 2.0;
|
||||
|
||||
/// Shift every vertex of a freshly tessellated `MeshLodSet` into the
|
||||
/// scene's local f32 space by subtracting `world_offset`. ACIS / SAT
|
||||
@@ -693,6 +676,14 @@ pub struct Scene {
|
||||
pub(crate) model_tiles: RefCell<Vec<ModelTile>>,
|
||||
/// Index of the active model tile (camera input + overlays target it).
|
||||
pub(crate) active_model_tile: std::cell::Cell<usize>,
|
||||
/// pane_grid layout tree for the Model tab — the source of truth for the
|
||||
/// tile split layout, resize and focus. `model_tiles` (the renderer's
|
||||
/// per-pane data: camera / render-mode / grid) is kept in lock-step with
|
||||
/// it, and its rects are derived from the pane regions. Each pane's value
|
||||
/// is the index of its backing `ModelTile`. Paper layout is unaffected.
|
||||
/// Plain field (not a `RefCell`) so the view can borrow it for the
|
||||
/// `PaneGrid` widget's lifetime; mutated through `&mut Scene` in update.
|
||||
pub(crate) model_panes: iced::widget::pane_grid::State<usize>,
|
||||
pub selection: Rc<RefCell<SelectionState>>,
|
||||
/// The CAD document — single source of truth for all entities.
|
||||
pub document: CadDocument,
|
||||
@@ -921,6 +912,8 @@ impl Scene {
|
||||
snap_on: false,
|
||||
}]),
|
||||
active_model_tile: std::cell::Cell::new(0),
|
||||
// One pane mapped to tile 0 — matches the single default tile above.
|
||||
model_panes: iced::widget::pane_grid::State::new(0).0,
|
||||
selection: Rc::new(RefCell::new(SelectionState::default())),
|
||||
document: CadDocument::new(),
|
||||
selected: HashSet::default(),
|
||||
|
||||
Reference in new issue
Block a user