Files
OneCAD-Draft/src/modules/draw/modify/block_edit.rs
T
Hakan SevenandClaude Fable 5 f03288f120 fix(bedit): restore the view when leaving the block editor
Entering the block editor reframes the camera on the block's own
geometry, but nothing remembered where the model view was — Save /
Discard returned to the layout with the camera still parked at the
editor's framing (#425). The session now captures the camera on entry
and both exits restore it exactly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 11:06:42 +03:00

103 lines
4.3 KiB
Rust

// BEDIT — block editor as a dedicated "space" tab (issue #261).
//
// Workflow:
// 1. BEDIT: user picks an INSERT (or has one pre-selected).
// 2. A block-editor space opens: rendering, picking and new geometry are
// scoped to the block's record, so ONLY the block's own (block-local)
// entities are drawn — no INSERT transform, they show exactly as stored.
// 3. The user edits them with normal commands. Because they ARE the block
// definition's entities, edits are live.
// 4. Save Block (BEDIT_SAVE): keep the edits and leave the block space.
// Discard (BEDIT_DISCARD): restore the block to its on-entry snapshot.
//
// Unlike REFEDIT (which copies entities into model space with the INSERT
// transform and inverse-transforms them back on save), a BEDIT space edits the
// block record in place, so there is no copy-back and no transform — the space
// render filter (`current_layout_block_handle`) already draws only the block.
use acadrust::{EntityType, Handle};
use glam::DVec3;
use crate::command::{CadCommand, CmdResult};
use crate::modules::{IconKind, ModuleEvent, ToolDef};
/// Right-edge side-toolbar buttons shown while a BEDIT block-editor space is
/// active: save the block edits and leave, or discard them.
pub fn block_edit_tools() -> Vec<ToolDef> {
vec![
ToolDef {
id: "BEDIT_SAVE",
label: "Save Block",
icon: IconKind::Svg(include_bytes!("../../../../assets/icons/mt_ok.svg")),
event: ModuleEvent::Command("BEDIT_SAVE".to_string()),
},
ToolDef {
id: "BEDIT_DISCARD",
label: "Discard Block Edit",
icon: IconKind::Svg(include_bytes!("../../../../assets/icons/mt_cancel.svg")),
event: ModuleEvent::Command("BEDIT_DISCARD".to_string()),
},
]
}
// ── Session state (held in DocumentTab) ───────────────────────────────────
/// Active BEDIT block-editor session. Lives in `DocumentTab::block_edit`.
#[derive(Clone)]
pub struct BlockEditSession {
/// Name of the block being edited (also the space-tab label).
pub block_name: String,
/// Handle of the block record whose entities are being edited.
pub br_handle: Handle,
/// Space to return to when the block editor closes (the layout that was
/// active when BEDIT began).
pub return_layout: String,
/// The block's block-local entities captured on entry, so Discard can
/// restore the definition (structural Block/BlockEnd/AttDef excluded).
pub snapshot: Vec<EntityType>,
/// Camera state of the space that was active when BEDIT began, restored
/// on Save/Discard so the view returns exactly where it was (#425).
pub return_camera: crate::scene::view::camera::Camera,
}
// ── BEDIT pick command ─────────────────────────────────────────────────────
/// Step 1: wait for the user to pick a single INSERT entity to edit.
pub struct BlockEditPickCommand;
impl BlockEditPickCommand {
pub fn new() -> Self {
Self
}
}
impl CadCommand for BlockEditPickCommand {
fn name(&self) -> &'static str {
"BEDIT"
}
fn prompt(&self) -> String {
"BEDIT Select block reference to edit:".into()
}
fn needs_entity_pick(&self) -> bool {
true
}
fn on_entity_pick(&mut self, handle: Handle, _pt: DVec3) -> CmdResult {
if handle.is_null() {
return CmdResult::NeedPoint;
}
// Signal the host to open the block-editor space for this INSERT.
CmdResult::Relaunch(format!("BEDIT_BEGIN:{}", handle.value()), vec![handle])
}
fn on_point(&mut self, _pt: DVec3) -> CmdResult {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult {
CmdResult::Cancel
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["BEDIT"] }); // BlockEditPickCommand
inventory::submit!(crate::command::CommandRegistration { names: &["BEDIT_SAVE"] });
inventory::submit!(crate::command::CommandRegistration { names: &["BEDIT_DISCARD"] });