From a2ad6fc44dc2e79b50a2aefbb5ee9de8daa38777 Mon Sep 17 00:00:00 2001 From: Zakru <23387227+Zakru@users.noreply.github.com> Date: Thu, 27 Jul 2023 23:07:55 +0300 Subject: [PATCH 1/3] Improve minimap controls --- .../controller/src/hud/minimap/interaction.rs | 130 ++++++++++++++---- 1 file changed, 105 insertions(+), 25 deletions(-) diff --git a/crates/controller/src/hud/minimap/interaction.rs b/crates/controller/src/hud/minimap/interaction.rs index e6812cd9..f17302cb 100644 --- a/crates/controller/src/hud/minimap/interaction.rs +++ b/crates/controller/src/hud/minimap/interaction.rs @@ -1,7 +1,10 @@ use std::fmt; use bevy::{ - input::{mouse::MouseButtonInput, ButtonState}, + input::{ + mouse::{MouseButtonInput, MouseMotion}, + ButtonState, + }, prelude::*, window::PrimaryWindow, }; @@ -19,35 +22,45 @@ pub(super) struct InteractionPlugin; impl Plugin for InteractionPlugin { fn build(&self, app: &mut App) { - app.add_event::().add_systems( - InputSchedule, - ( - click_handler.in_set(InteractionSet::ClickHandler), - move_camera_system.after(InteractionSet::ClickHandler), - send_units_system - .after(InteractionSet::ClickHandler) - .before(CommandsSet::SendSelected), - delivery_location_system - .after(InteractionSet::ClickHandler) - .before(CommandsSet::DeliveryLocation), - ) - .run_if(in_state(GameState::Playing)), - ); + app.add_event::() + .add_event::() + .insert_resource(DraggingButtons(Vec::new())) + .add_systems( + InputSchedule, + ( + click_handler + .in_set(InteractionSet::ClickHandler) + .run_if(on_event::()), + drag_handler + .in_set(InteractionSet::DragHandler) + .after(InteractionSet::ClickHandler) + .run_if(on_event::()), + move_camera_system.after(InteractionSet::DragHandler), + send_units_system + .after(InteractionSet::ClickHandler) + .before(CommandsSet::SendSelected), + delivery_location_system + .after(InteractionSet::ClickHandler) + .before(CommandsSet::DeliveryLocation), + ) + .run_if(in_state(GameState::Playing)), + ); } } #[derive(Copy, Clone, Hash, Debug, PartialEq, Eq, SystemSet)] enum InteractionSet { ClickHandler, + DragHandler, } #[derive(Event)] -struct MinimapClickEvent { +struct MinimapPressEvent { button: MouseButton, position: Vec2, } -impl MinimapClickEvent { +impl MinimapPressEvent { fn new(button: MouseButton, position: Vec2) -> Self { Self { button, position } } @@ -63,50 +76,117 @@ impl MinimapClickEvent { } } -impl fmt::Debug for MinimapClickEvent { +impl fmt::Debug for MinimapPressEvent { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?} -> {:?}", self.button, self.position) } } +#[derive(Event)] +struct MinimapDragEvent { + button: MouseButton, + position: Vec2, +} + +impl MinimapDragEvent { + fn new(button: MouseButton, position: Vec2) -> Self { + Self { button, position } + } + + fn button(&self) -> MouseButton { + self.button + } + + /// Position on the map in 2D flat coordinates (these are not minimap + /// coordinates). + fn position(&self) -> Vec2 { + self.position + } +} + +#[derive(Resource)] +struct DraggingButtons(Vec); + fn click_handler( window_query: Query<&Window, With>, mut input_events: EventReader, hud: HudNodes>, bounds: Res, - mut click_events: EventWriter, + mut dragging: ResMut, + mut click_events: EventWriter, ) { let Some(cursor) = window_query.single().cursor_position() else { return; }; + for event in input_events.iter() { - if event.state != ButtonState::Released { + if event.state != ButtonState::Pressed { + dragging.0.retain(|b| *b != event.button); continue; } if let Some(mut relative) = hud.relative_position(cursor) { + dragging.0.push(event.button); relative.y = 1. - relative.y; - let event = MinimapClickEvent::new(event.button, bounds.rel_to_abs(relative)); + let event = MinimapPressEvent::new(event.button, bounds.rel_to_abs(relative)); info!("Sending minimap click event {event:?}."); click_events.send(event); } } } +fn drag_handler( + window_query: Query<&Window, With>, + hud: HudNodes>, + bounds: Res, + dragging: Res, + mut drag_events: EventWriter, +) { + if dragging.0.is_empty() { + return; + } + + let Some(cursor) = window_query.single().cursor_position() else { + return; + }; + + if let Some(relative) = hud.relative_position(cursor) { + let proportional = Vec2::new(relative.x, 1. - relative.y); + let world = bounds.rel_to_abs(proportional); + + for b in &dragging.0 { + let event = MinimapDragEvent::new(*b, world); + drag_events.send(event); + } + } +} + fn move_camera_system( - mut click_events: EventReader, + mut click_events: EventReader, + mut drag_events: EventReader, mut camera_events: EventWriter, ) { for click in click_events.iter() { if click.button() != MouseButton::Left { continue; } - camera_events.send(MoveFocusEvent::new(click.position())); + + let event = MoveFocusEvent::new(click.position()); + camera_events.send(event); + } + + for drag in drag_events.iter() { + if drag.button() != MouseButton::Left { + continue; + } + + let event = MoveFocusEvent::new(drag.position()); + camera_events.send(event); } } fn send_units_system( - mut click_events: EventReader, + mut click_events: EventReader, mut send_events: EventWriter, ) { for click in click_events.iter() { @@ -118,7 +198,7 @@ fn send_units_system( } fn delivery_location_system( - mut click_events: EventReader, + mut click_events: EventReader, mut location_events: EventWriter, ) { for click in click_events.iter() { From 4ac876ea5fbe4e2dabe668228f8d6cb5c443ee2c Mon Sep 17 00:00:00 2001 From: Zakru <23387227+Zakru@users.noreply.github.com> Date: Mon, 31 Jul 2023 00:49:43 +0300 Subject: [PATCH 2/3] Minimap PR improvements --- .../controller/src/hud/minimap/interaction.rs | 68 ++++++++++--------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/crates/controller/src/hud/minimap/interaction.rs b/crates/controller/src/hud/minimap/interaction.rs index f17302cb..2d7b16d7 100644 --- a/crates/controller/src/hud/minimap/interaction.rs +++ b/crates/controller/src/hud/minimap/interaction.rs @@ -28,19 +28,21 @@ impl Plugin for InteractionPlugin { .add_systems( InputSchedule, ( - click_handler - .in_set(InteractionSet::ClickHandler) + press_handler + .in_set(InteractionSet::PressHandler) .run_if(on_event::()), drag_handler .in_set(InteractionSet::DragHandler) - .after(InteractionSet::ClickHandler) + .after(InteractionSet::PressHandler) .run_if(on_event::()), - move_camera_system.after(InteractionSet::DragHandler), + move_camera_system + .after(InteractionSet::PressHandler) + .after(InteractionSet::DragHandler), send_units_system - .after(InteractionSet::ClickHandler) + .after(InteractionSet::PressHandler) .before(CommandsSet::SendSelected), delivery_location_system - .after(InteractionSet::ClickHandler) + .after(InteractionSet::PressHandler) .before(CommandsSet::DeliveryLocation), ) .run_if(in_state(GameState::Playing)), @@ -50,7 +52,7 @@ impl Plugin for InteractionPlugin { #[derive(Copy, Clone, Hash, Debug, PartialEq, Eq, SystemSet)] enum InteractionSet { - ClickHandler, + PressHandler, DragHandler, } @@ -104,33 +106,35 @@ impl MinimapDragEvent { } } -#[derive(Resource)] +#[derive(Resource, Deref, DerefMut)] struct DraggingButtons(Vec); -fn click_handler( +fn press_handler( window_query: Query<&Window, With>, mut input_events: EventReader, hud: HudNodes>, bounds: Res, mut dragging: ResMut, - mut click_events: EventWriter, + mut press_events: EventWriter, ) { - let Some(cursor) = window_query.single().cursor_position() else { - return; - }; + let cursor = window_query.single().cursor_position(); for event in input_events.iter() { if event.state != ButtonState::Pressed { - dragging.0.retain(|b| *b != event.button); + dragging.retain(|b| *b != event.button); continue; } + let Some(cursor) = cursor else { + continue; + }; + if let Some(mut relative) = hud.relative_position(cursor) { - dragging.0.push(event.button); + dragging.push(event.button); relative.y = 1. - relative.y; let event = MinimapPressEvent::new(event.button, bounds.rel_to_abs(relative)); - info!("Sending minimap click event {event:?}."); - click_events.send(event); + info!("Sending minimap press event {event:?}."); + press_events.send(event); } } } @@ -142,7 +146,7 @@ fn drag_handler( dragging: Res, mut drag_events: EventWriter, ) { - if dragging.0.is_empty() { + if dragging.is_empty() { return; } @@ -154,24 +158,24 @@ fn drag_handler( let proportional = Vec2::new(relative.x, 1. - relative.y); let world = bounds.rel_to_abs(proportional); - for b in &dragging.0 { - let event = MinimapDragEvent::new(*b, world); + for button in &**dragging { + let event = MinimapDragEvent::new(*button, world); drag_events.send(event); } } } fn move_camera_system( - mut click_events: EventReader, + mut press_events: EventReader, mut drag_events: EventReader, mut camera_events: EventWriter, ) { - for click in click_events.iter() { - if click.button() != MouseButton::Left { + for press in press_events.iter() { + if press.button() != MouseButton::Left { continue; } - let event = MoveFocusEvent::new(click.position()); + let event = MoveFocusEvent::new(press.position()); camera_events.send(event); } @@ -186,25 +190,25 @@ fn move_camera_system( } fn send_units_system( - mut click_events: EventReader, + mut press_events: EventReader, mut send_events: EventWriter, ) { - for click in click_events.iter() { - if click.button() != MouseButton::Right { + for press in press_events.iter() { + if press.button() != MouseButton::Right { continue; } - send_events.send(SendSelectedEvent::new(click.position())); + send_events.send(SendSelectedEvent::new(press.position())); } } fn delivery_location_system( - mut click_events: EventReader, + mut press_events: EventReader, mut location_events: EventWriter, ) { - for click in click_events.iter() { - if click.button() != MouseButton::Right { + for press in press_events.iter() { + if press.button() != MouseButton::Right { continue; } - location_events.send(DeliveryLocationSelectedEvent::new(click.position())); + location_events.send(DeliveryLocationSelectedEvent::new(press.position())); } } From 5dd2933fe5a3eb84fc4c4ab8e531a10b2445d61a Mon Sep 17 00:00:00 2001 From: Zakru <23387227+Zakru@users.noreply.github.com> Date: Thu, 7 Sep 2023 17:00:05 +0300 Subject: [PATCH 3/3] Match mouse button instead of inequality check --- crates/controller/src/hud/minimap/interaction.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/controller/src/hud/minimap/interaction.rs b/crates/controller/src/hud/minimap/interaction.rs index 2d7b16d7..441f838e 100644 --- a/crates/controller/src/hud/minimap/interaction.rs +++ b/crates/controller/src/hud/minimap/interaction.rs @@ -120,9 +120,12 @@ fn press_handler( let cursor = window_query.single().cursor_position(); for event in input_events.iter() { - if event.state != ButtonState::Pressed { - dragging.retain(|b| *b != event.button); - continue; + match event.state { + ButtonState::Released => { + dragging.retain(|b| *b != event.button); + continue; + } + ButtonState::Pressed => (), } let Some(cursor) = cursor else {