From d66673a4fa58e44f0a8f89b2d1847cfb22866c09 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Thu, 2 Apr 2026 23:13:09 +0300 Subject: [PATCH] =?UTF-8?q?Feat:=20VPLAYER=20ALL=20=E2=80=94=20freeze/thaw?= =?UTF-8?q?=20layer=20across=20all=20viewports=20in=20layout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- src/app/cmd_result.rs | 44 ++++++++++++++++++++++++----------- src/modules/layout/vplayer.rs | 35 ++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/app/cmd_result.rs b/src/app/cmd_result.rs index a840f081..f229d6f3 100644 --- a/src/app/cmd_result.rs +++ b/src/app/cmd_result.rs @@ -286,7 +286,8 @@ impl H7CAD { } } CmdResult::VpLayerUpdate { vp_handle, freeze, thaw } => { - // Resolve layer names → handles, then update frozen_layers on the viewport. + // Resolve layer names → handles, then update frozen_layers on the viewport(s). + // vp_handle == Handle::NULL means "apply to all viewports in current layout". let freeze_handles: Vec = freeze.iter() .filter_map(|name| { self.tabs[i].scene.document.layers.iter() @@ -305,19 +306,36 @@ impl H7CAD { 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; + // Collect target viewport handles + let target_handles: Vec = if vp_handle == acadrust::Handle::NULL { + // All viewports in current layout block + let block_handle = self.tabs[i].scene.current_layout_block_handle_pub(); + self.tabs[i].scene.document.entities() + .filter(|e| { + e.common().owner_handle == block_handle + && matches!(e, acadrust::EntityType::Viewport(_)) + }) + .map(|e| e.common().handle) + .collect() + } else { + vec![vp_handle] + }; + + for &target_handle in &target_handles { + if let Some(acadrust::EntityType::Viewport(vp)) = + self.tabs[i].scene.document.get_entity_mut(target_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; } } - } - 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; } } } diff --git a/src/modules/layout/vplayer.rs b/src/modules/layout/vplayer.rs index e005f836..329f0c1b 100644 --- a/src/modules/layout/vplayer.rs +++ b/src/modules/layout/vplayer.rs @@ -2,9 +2,11 @@ // // Usage (command line): // VPLAYER -// > F → freeze layer in active viewport -// > T → thaw layer in active viewport -// > Enter → exit +// > F → freeze layer in active viewport +// > T → thaw layer in active viewport +// > F ALL → freeze layer in ALL viewports +// > T ALL → thaw layer in ALL viewports +// > Enter → exit // // Layer names are case-insensitive. Multiple space-separated names are accepted. @@ -43,12 +45,22 @@ impl CadCommand for VplayerCommand { return Some(CmdResult::Cancel); } - let mut parts = text.splitn(2, char::is_whitespace); - let op = parts.next().unwrap_or("").to_uppercase(); - let rest = parts.next().unwrap_or("").trim(); + let tokens: Vec<&str> = text.split_whitespace().collect(); + if tokens.is_empty() { + return None; + } - let layer_names: Vec = rest - .split_whitespace() + let op = tokens[0].to_uppercase(); + + // Check for ALL keyword: "F ALL layer1 layer2" or "T ALL layer1" + let (all_viewports, layer_start) = if tokens.get(1).map(|s| s.to_uppercase().as_str() == "ALL").unwrap_or(false) { + (true, 2) + } else { + (false, 1) + }; + + let layer_names: Vec = tokens[layer_start..] + .iter() .map(|s| s.to_string()) .collect(); @@ -56,14 +68,17 @@ impl CadCommand for VplayerCommand { return None; // no layer name given — ignore and re-prompt } + // Handle::NULL signals "apply to all viewports" in cmd_result.rs + let vp_handle = if all_viewports { acadrust::Handle::NULL } else { self.vp_handle }; + match op.as_str() { "F" | "FREEZE" => Some(CmdResult::VpLayerUpdate { - vp_handle: self.vp_handle, + vp_handle, freeze: layer_names, thaw: vec![], }), "T" | "THAW" => Some(CmdResult::VpLayerUpdate { - vp_handle: self.vp_handle, + vp_handle, freeze: vec![], thaw: layer_names, }),