|
1 | 1 | use crate::gui::input::CurrentLayer; |
| 2 | +use crate::gui::layer_ext::get_extension_for_layer; |
2 | 3 | use crate::gui::node::{NeedsScaling, NodeEntity, NodeSvg}; |
3 | 4 | use crate::gui::queries; |
4 | 5 | use bevy::prelude::*; |
5 | 6 | use bevy_svg::prelude::{Origin, Svg2d}; |
6 | | -use sandpolis_core::LayerName; |
| 7 | +use sandpolis_core::{InstanceType, LayerName}; |
7 | 8 |
|
8 | 9 | /// Update node SVG images when layer changes or for newly spawned nodes |
9 | 10 | pub fn update_node_svgs_for_layer( |
@@ -208,3 +209,71 @@ fn get_layer_color_tint( |
208 | 209 | _ => Color::WHITE, // No tint for other layers |
209 | 210 | } |
210 | 211 | } |
| 212 | + |
| 213 | +/// Update node visibility based on the current layer's visible instance types. |
| 214 | +/// |
| 215 | +/// Each layer can specify which instance types (Server, Agent, Client) should be |
| 216 | +/// visible when that layer is active. This system hides nodes that don't match |
| 217 | +/// the current layer's filter criteria. |
| 218 | +pub fn update_node_visibility_for_layer( |
| 219 | + current_layer: Res<CurrentLayer>, |
| 220 | + mut node_query: Query<(&NodeEntity, &mut Visibility)>, |
| 221 | +) { |
| 222 | + // Only update when layer changes |
| 223 | + if !current_layer.is_changed() { |
| 224 | + return; |
| 225 | + } |
| 226 | + |
| 227 | + // Get the visible instance types for the current layer |
| 228 | + let visible_types = get_visible_instance_types_for_layer(¤t_layer); |
| 229 | + |
| 230 | + for (node_entity, mut visibility) in node_query.iter_mut() { |
| 231 | + let instance_id = node_entity.instance_id; |
| 232 | + |
| 233 | + // Check if this node's instance type matches any of the visible types |
| 234 | + let should_be_visible = visible_types.iter().any(|instance_type| { |
| 235 | + instance_id.is_type(*instance_type) |
| 236 | + }); |
| 237 | + |
| 238 | + *visibility = if should_be_visible { |
| 239 | + Visibility::Inherited |
| 240 | + } else { |
| 241 | + Visibility::Hidden |
| 242 | + }; |
| 243 | + } |
| 244 | +} |
| 245 | + |
| 246 | +/// Get the visible instance types for a layer. |
| 247 | +/// |
| 248 | +/// This checks if there's a LayerGuiExtension for the layer and uses its |
| 249 | +/// visible_instance_types() method. If no extension exists, falls back to |
| 250 | +/// default behavior based on layer name. |
| 251 | +fn get_visible_instance_types_for_layer(layer: &LayerName) -> &'static [InstanceType] { |
| 252 | + // First, check if there's a registered extension for this layer |
| 253 | + if let Some(ext) = get_extension_for_layer(layer) { |
| 254 | + return ext.visible_instance_types(); |
| 255 | + } |
| 256 | + |
| 257 | + // Fall back to default behavior based on layer name |
| 258 | + match layer.name() { |
| 259 | + // Network layer shows all instance types |
| 260 | + "Network" => &[InstanceType::Server, InstanceType::Agent, InstanceType::Client], |
| 261 | + |
| 262 | + // Agent-focused layers only show servers and agents |
| 263 | + "Inventory" | "Filesystem" | "Shell" | "Desktop" | "Probe" => { |
| 264 | + &[InstanceType::Server, InstanceType::Agent] |
| 265 | + } |
| 266 | + |
| 267 | + // Client layer only shows servers and clients |
| 268 | + "Client" => &[InstanceType::Server, InstanceType::Client], |
| 269 | + |
| 270 | + // Server layer only shows servers |
| 271 | + "Server" => &[InstanceType::Server], |
| 272 | + |
| 273 | + // Agent layer only shows servers and agents |
| 274 | + "Agent" => &[InstanceType::Server, InstanceType::Agent], |
| 275 | + |
| 276 | + // Default: show all |
| 277 | + _ => &[InstanceType::Server, InstanceType::Agent, InstanceType::Client], |
| 278 | + } |
| 279 | +} |
0 commit comments