M crates/unified/src/ship_editor/components.rs => crates/unified/src/ship_editor/components.rs +2 -0
@@ 20,6 20,8 @@ pub struct Selectable {
pub outline_entity: Option<Entity>,
pub is_selected: bool,
}
+#[derive(Resource, Default)]
+pub struct SelectedCount(pub usize);
#[derive(Component, Default, Clone, Copy, ExtractComponent)]
pub struct OutlineCamera;
M crates/unified/src/ship_editor/mod.rs => crates/unified/src/ship_editor/mod.rs +2 -1
@@ 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::<InputFocus>()
+ .init_resource::<SelectedCount>()
.add_systems(Startup, setup)
.add_systems(Update, (spawn_player_part_request, spawn_parts))
.add_plugins(input_plugin)
M crates/unified/src/ship_editor/select.rs => crates/unified/src/ship_editor/select.rs +21 -4
@@ 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<Pointer<Click>>,
+ keys: Res<ButtonInput<KeyCode>>,
mut parts: Query<(Entity, &Transform, &PartConfigHolder, &mut Selectable), With<Part>>,
drag: Res<ShipEditorDrag>,
+ mut selected_count: ResMut<SelectedCount>,
mut commands: Commands,
asset_server: Res<AssetServer>,
) {
- 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