forked from 1b-agent/opencadstudio-upstream
Feat: viewport display lock, extended properties, VPLAYER and VPORTS commands
- Enforce status.locked in pan_active_viewport and zoom_active_viewport: locked viewports now reject pan/zoom inputs entirely - Add perspective, render_mode, shade_plot_mode, hide_plot, ucs_icon_visible fields to the viewport property panel with appropriate pickers/toggles - Add VPORTS command: lists all user viewports in the current layout (id, size, position, scale, on/locked state) in the command line - Add VPLAYER command: per-viewport layer freeze/thaw from the command line (F <layer> to freeze, T <layer> to thaw, Enter to exit) - Add CmdResult::VpLayerUpdate variant and its handler in apply_cmd_result Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
b013619c25
commit
73b224c191
7 files changed
+311
-1
No files matched your search
@@ -285,6 +285,59 @@ impl H7CAD {
|
||||
self.command_line.push_info("No groups found for selected objects.");
|
||||
}
|
||||
}
|
||||
CmdResult::VpLayerUpdate { vp_handle, freeze, thaw } => {
|
||||
// Resolve layer names → handles, then update frozen_layers on the viewport.
|
||||
let freeze_handles: Vec<Handle> = freeze.iter()
|
||||
.filter_map(|name| {
|
||||
self.tabs[i].scene.document.layers.iter()
|
||||
.find(|l| l.name.eq_ignore_ascii_case(name))
|
||||
.map(|l| l.handle)
|
||||
})
|
||||
.collect();
|
||||
let thaw_handles: Vec<Handle> = thaw.iter()
|
||||
.filter_map(|name| {
|
||||
self.tabs[i].scene.document.layers.iter()
|
||||
.find(|l| l.name.eq_ignore_ascii_case(name))
|
||||
.map(|l| l.handle)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut frozen_count = 0usize;
|
||||
let mut thawed_count = 0usize;
|
||||
|
||||
if let Some(acadrust::EntityType::Viewport(vp)) =
|
||||
self.tabs[i].scene.document.get_entity_mut(vp_handle)
|
||||
{
|
||||
for h in &freeze_handles {
|
||||
if !vp.frozen_layers.contains(h) {
|
||||
vp.frozen_layers.push(*h);
|
||||
frozen_count += 1;
|
||||
}
|
||||
}
|
||||
for h in &thaw_handles {
|
||||
let before = vp.frozen_layers.len();
|
||||
vp.frozen_layers.retain(|fh| fh != h);
|
||||
if vp.frozen_layers.len() < before { thawed_count += 1; }
|
||||
}
|
||||
}
|
||||
|
||||
if frozen_count > 0 || thawed_count > 0 {
|
||||
self.push_undo_snapshot(i, "VPLAYER");
|
||||
self.tabs[i].dirty = true;
|
||||
if frozen_count > 0 {
|
||||
self.command_line.push_info(&format!("VPLAYER: {frozen_count} layer(s) frozen in viewport."));
|
||||
}
|
||||
if thawed_count > 0 {
|
||||
self.command_line.push_info(&format!("VPLAYER: {thawed_count} layer(s) thawed in viewport."));
|
||||
}
|
||||
}
|
||||
|
||||
// Show updated prompt (command stays active for more operations).
|
||||
let prompt = self.tabs[i].active_cmd.as_ref().map(|c| c.prompt());
|
||||
if let Some(p) = prompt {
|
||||
self.command_line.push_info(&p);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Focus the command-line input while a command is active; blur it when the command ends.
|
||||
if self.tabs[i].active_cmd.is_some() {
|
||||
|
||||
@@ -909,6 +909,75 @@ impl H7CAD {
|
||||
return Task::done(Message::PspaceCommand);
|
||||
}
|
||||
|
||||
// ── VPORTS — list viewports in current layout ─────────────────
|
||||
"VPORTS" => {
|
||||
let scene = &self.tabs[i].scene;
|
||||
if scene.current_layout == "Model" {
|
||||
self.command_line.push_error("VPORTS: switch to a paper space layout first.");
|
||||
} else {
|
||||
let layout_block = scene.current_layout_block_handle_pub();
|
||||
let viewports: Vec<_> = scene.document.entities()
|
||||
.filter_map(|e| {
|
||||
if let acadrust::EntityType::Viewport(vp) = e {
|
||||
if vp.id > 1 && vp.common.owner_handle == layout_block {
|
||||
Some((vp.id, vp.center.clone(), vp.width, vp.height, vp.custom_scale, vp.status.is_on, vp.status.locked))
|
||||
} else { None }
|
||||
} else { None }
|
||||
})
|
||||
.collect();
|
||||
if viewports.is_empty() {
|
||||
self.command_line.push_info("No viewports in current layout. Use MVIEW to create one.");
|
||||
} else {
|
||||
self.command_line.push_output(&format!("{} viewport(s) in layout \"{}\":", viewports.len(), scene.current_layout));
|
||||
for (id, center, w, h, scale, is_on, locked) in &viewports {
|
||||
let state = match (is_on, locked) {
|
||||
(true, true) => "On, Locked",
|
||||
(true, false) => "On",
|
||||
(false, _) => "Off",
|
||||
};
|
||||
self.command_line.push_output(&format!(
|
||||
" VP #{id}: {w:.1}×{h:.1} @ ({:.1},{:.1}) scale={scale:.4} [{state}]",
|
||||
center.x, center.y
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── VPLAYER — per-viewport layer freeze/thaw ──────────────────
|
||||
"VPLAYER" => {
|
||||
let scene = &self.tabs[i].scene;
|
||||
if scene.current_layout == "Model" {
|
||||
self.command_line.push_error("VPLAYER: switch to a paper space layout first.");
|
||||
} else if scene.active_viewport.is_none() {
|
||||
self.command_line.push_error("VPLAYER: enter a viewport first (double-click or MS).");
|
||||
} else {
|
||||
use crate::modules::layout::vplayer::VplayerCommand;
|
||||
let vp_handle = scene.active_viewport.unwrap();
|
||||
// Collect current frozen layer names for display.
|
||||
let frozen_names: Vec<String> = {
|
||||
if let Some(acadrust::EntityType::Viewport(vp)) =
|
||||
scene.document.get_entity(vp_handle)
|
||||
{
|
||||
vp.frozen_layers.iter().filter_map(|h| {
|
||||
scene.document.layers.iter().find(|l| l.handle == *h).map(|l| l.name.clone())
|
||||
}).collect()
|
||||
} else { vec![] }
|
||||
};
|
||||
if frozen_names.is_empty() {
|
||||
self.command_line.push_info("VPLAYER: no frozen layers in active viewport.");
|
||||
} else {
|
||||
self.command_line.push_info(&format!(
|
||||
"VPLAYER: frozen layers: {}",
|
||||
frozen_names.join(", ")
|
||||
));
|
||||
}
|
||||
let new_cmd = VplayerCommand::new(vp_handle);
|
||||
self.command_line.push_info(&new_cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
|
||||
}
|
||||
}
|
||||
|
||||
// ── Plot / Page Setup ──────────────────────────────────────────
|
||||
"PRINT"|"PLOT"|"EXPORT" => {
|
||||
return Task::done(Message::PlotExport);
|
||||
|
||||
Reference in new issue
Block a user