From 785a5a087f78903b09c8e0cbcf1454bbe44c114f Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Fri, 19 Jun 2026 17:06:41 -0500 Subject: [PATCH] ship editor feat: shift clicking and regular clicking work how they probably should --- crates/unified/src/ship_editor/components.rs | 2 ++ crates/unified/src/ship_editor/mod.rs | 3 ++- crates/unified/src/ship_editor/select.rs | 25 ++++++++++++++++---- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/crates/unified/src/ship_editor/components.rs b/crates/unified/src/ship_editor/components.rs index 70302499b11120e15fdfecd003aae919c38a71b3..d6a9f190ca6549f61f89d63a11ea9751d2771896 100644 --- a/crates/unified/src/ship_editor/components.rs +++ b/crates/unified/src/ship_editor/components.rs @@ -20,6 +20,8 @@ pub struct Selectable { pub outline_entity: Option, pub is_selected: bool, } +#[derive(Resource, Default)] +pub struct SelectedCount(pub usize); #[derive(Component, Default, Clone, Copy, ExtractComponent)] pub struct OutlineCamera; diff --git a/crates/unified/src/ship_editor/mod.rs b/crates/unified/src/ship_editor/mod.rs index 01cd0e2e1f65e67057e4e9448c631b40a7d7145a..9d4826b943c57a06133b0c6424c4c29ddf7e06a9 100644 --- a/crates/unified/src/ship_editor/mod.rs +++ b/crates/unified/src/ship_editor/mod.rs @@ -10,7 +10,7 @@ use crate::prelude::*; use crate::shared::attachment::{Joint, JointId, JointOf, SnapOf, SnapOfJoint}; use crate::shared::config::part::{JointConfig, PartConfig}; use crate::shared::config::ship_editor::ShipEditorConfig; -use crate::ship_editor::components::{GhostCamera, MainCamera, OutlineCamera, Part, PartConfigHolder, PlayerPartRequest, Selectable, ShipEditorConfigHolder, SpawnPartRequest, GHOST_RENDER_LAYER, MAIN_RENDER_LAYER, OUTLINE_RENDER_LAYER}; +use crate::ship_editor::components::{GhostCamera, MainCamera, OutlineCamera, Part, PartConfigHolder, PlayerPartRequest, Selectable, SelectedCount, ShipEditorConfigHolder, SpawnPartRequest, GHOST_RENDER_LAYER, MAIN_RENDER_LAYER, OUTLINE_RENDER_LAYER}; use crate::ship_editor::input::input_plugin; use crate::ship_editor::select::click_select; use crate::ship_editor::ui::{ui_plugin, PendingPart}; @@ -21,6 +21,7 @@ impl Plugin for ShipEditorPlugin { fn build(&self, app: &mut App) { app .init_resource::() + .init_resource::() .add_systems(Startup, setup) .add_systems(Update, (spawn_player_part_request, spawn_parts)) .add_plugins(input_plugin) diff --git a/crates/unified/src/ship_editor/select.rs b/crates/unified/src/ship_editor/select.rs index c67a7fa0d98d8bf4d6c44fa05a77447d693be3e1..e803c9bd5b350b1d07ccea909a1f191f68711c83 100644 --- a/crates/unified/src/ship_editor/select.rs +++ b/crates/unified/src/ship_editor/select.rs @@ -1,21 +1,22 @@ use crate::prelude::*; -use crate::ship_editor::components::{Part, PartConfigHolder, Selectable, OUTLINE_RENDER_LAYER}; +use crate::ship_editor::components::{Part, PartConfigHolder, Selectable, SelectedCount, OUTLINE_RENDER_LAYER}; use crate::ship_editor::input::ShipEditorDrag; pub fn click_select( ev: On>, + keys: Res>, mut parts: Query<(Entity, &Transform, &PartConfigHolder, &mut Selectable), With>, drag: Res, + mut selected_count: ResMut, mut commands: Commands, asset_server: Res, ) { - debug!("click detected"); if !drag.can_select { return } + let Ok((part_entity, part_transform, part, mut part_selectable)) = parts.get_mut(ev.entity) else { error!("No Part found upon part selection. The observer probably wasn't removed."); return; }; - if !part_selectable.is_selected { let mut sprite = Sprite::from_image(asset_server.load("textures/outline.png")); sprite.custom_size = Some(vec2(part.0.physics.width as f32, part.0.physics.height as f32) * 1.0625); @@ -25,10 +26,26 @@ pub fn click_select( )); part_selectable.outline_entity = Some(outline_entity.id()); part_selectable.is_selected = true; - } else { + selected_count.0 += 1; + } else { 'select: { + if !(keys.pressed(KeyCode::ShiftLeft) || keys.pressed(KeyCode::ShiftRight)) && selected_count.0 > 1 { break 'select; } part_selectable.is_selected = false; if let Some(outline_entity) = part_selectable.outline_entity { commands.entity(outline_entity).despawn(); } + part_selectable.outline_entity = None; + selected_count.0 -= 1; + } } + if !(keys.pressed(KeyCode::ShiftLeft) || keys.pressed(KeyCode::ShiftRight)) { + for (part_entity, part_transform, part, mut part_selectable) in parts.iter_mut() { + if part_entity == ev.entity { continue } + + if let Some(outline_entity) = part_selectable.outline_entity { + part_selectable.is_selected = false; + commands.entity(outline_entity).despawn(); + part_selectable.outline_entity = None; + selected_count.0 -= 1; + } + } } } \ No newline at end of file