Skip to content

Commit a7b8a5f

Browse files
committed
fix buttons
1 parent 42ea546 commit a7b8a5f

2 files changed

Lines changed: 64 additions & 25 deletions

File tree

solitaire-game/src/buttons.rs

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bevy::{
22
ecs::entity_disabling::Disabled,
3-
input::common_conditions::input_just_pressed,
3+
input::common_conditions::{input_just_pressed, input_just_released},
44
prelude::*,
55
window::{PrimaryWindow, RequestRedraw},
66
};
@@ -19,12 +19,20 @@ impl Plugin for Buttons {
1919
app.add_systems(
2020
Update,
2121
(
22-
handle_button::<Undo, UndoEvent>.run_if(input_just_pressed(MouseButton::Left)),
23-
handle_button::<Reset, ResetEvent>.run_if(input_just_pressed(MouseButton::Left)),
24-
handle_toggle::<Hints, ToggleHints>.run_if(input_just_pressed(MouseButton::Left)),
25-
handle_toggle::<Stats, ToggleStats>.run_if(input_just_pressed(MouseButton::Left)),
26-
handle_touch_button::<Undo, UndoEvent>,
27-
handle_touch_button::<Reset, ResetEvent>,
22+
handle_button_press::<Undo, UndoEvent>
23+
.run_if(input_just_pressed(MouseButton::Left)),
24+
handle_button_press::<Reset, ResetEvent>
25+
.run_if(input_just_pressed(MouseButton::Left)),
26+
handle_button_release::<Undo>.run_if(input_just_released(MouseButton::Left)),
27+
handle_button_release::<Reset>.run_if(input_just_released(MouseButton::Left)),
28+
handle_toggle_press::<Hints, ToggleHints>
29+
.run_if(input_just_pressed(MouseButton::Left)),
30+
handle_toggle_press::<Stats, ToggleStats>
31+
.run_if(input_just_pressed(MouseButton::Left)),
32+
handle_touch_press::<Undo, UndoEvent>,
33+
handle_touch_press::<Reset, ResetEvent>,
34+
handle_touch_release::<Undo>,
35+
handle_touch_release::<Reset>,
2836
handle_touch_toggle::<Hints, ToggleHints>,
2937
handle_touch_toggle::<Stats, ToggleStats>,
3038
),
@@ -63,7 +71,10 @@ struct CircleButton {
6371
}
6472

6573
#[derive(Component)]
66-
struct ButtonState(bool);
74+
struct ButtonState {
75+
clicked: bool,
76+
touched: Option<u64>,
77+
}
6778

6879
#[derive(Component)]
6980
struct ToggleState(bool);
@@ -113,7 +124,10 @@ fn add_buttons(mut commands: Commands, asset_server: Res<AssetServer>) {
113124
bg_color: Color::BLACK,
114125
radius: 0.4,
115126
},
116-
ButtonState(false),
127+
ButtonState {
128+
clicked: false,
129+
touched: None,
130+
},
117131
Text2d::new("\u{f2ea}".to_string()),
118132
TextColor(Color::BLACK),
119133
font_awesome.clone(),
@@ -128,7 +142,10 @@ fn add_buttons(mut commands: Commands, asset_server: Res<AssetServer>) {
128142
bg_color: Color::BLACK,
129143
radius: 0.3,
130144
},
131-
ButtonState(false),
145+
ButtonState {
146+
clicked: false,
147+
touched: None,
148+
},
132149
Text2d::new("\u{f060}".to_string()),
133150
TextColor(Color::BLACK),
134151
font_awesome.clone(),
@@ -165,7 +182,7 @@ fn add_buttons(mut commands: Commands, asset_server: Res<AssetServer>) {
165182
));
166183
}
167184

168-
fn handle_button<'a, T, U: Default + Event>(
185+
fn handle_button_press<'a, T, U: Default + Event>(
169186
window: Single<&Window, With<PrimaryWindow>>,
170187
camera: Single<(&Camera, &GlobalTransform)>,
171188
mut button: Query<(&CircleButton, &mut ButtonState, &Transform), With<T>>,
@@ -182,15 +199,22 @@ fn handle_button<'a, T, U: Default + Event>(
182199
for (button, mut state, transform) in &mut button {
183200
if world_pos.xy().distance(transform.translation.xy()) < button.radius {
184201
commands.trigger(U::default());
185-
state.0 = true;
186-
} else {
187-
state.0 = false;
202+
state.clicked = true;
188203
}
189204
}
190205
}
191206
}
192207

193-
fn handle_toggle<'a, T, U: Default + Event>(
208+
fn handle_button_release<T>(mut button: Query<&mut ButtonState, With<T>>)
209+
where
210+
T: Component + Send + Sync,
211+
{
212+
for mut state in &mut button {
213+
state.clicked = false;
214+
}
215+
}
216+
217+
fn handle_toggle_press<'a, T, U: Default + Event>(
194218
window: Single<&Window, With<PrimaryWindow>>,
195219
camera: Single<(&Camera, &GlobalTransform)>,
196220
mut button: Query<(&CircleButton, &mut ToggleState, &Transform), With<T>>,
@@ -213,32 +237,47 @@ fn handle_toggle<'a, T, U: Default + Event>(
213237
}
214238
}
215239

216-
fn handle_touch_button<'a, T, U: Default + Event>(
240+
fn handle_touch_press<'a, T, U: Default + Event>(
217241
camera: Single<(&Camera, &GlobalTransform)>,
218-
mut button: Query<(&CircleButton, &mut ButtonState, &Transform), With<T>>,
242+
mut buttons: Query<(&CircleButton, &mut ButtonState, &Transform), With<T>>,
219243
mut commands: Commands,
220244
touches: Res<Touches>,
221245
) where
222246
T: Component + Send + Sync,
223247
<U as bevy::prelude::Event>::Trigger<'a>: std::default::Default,
224248
{
225-
for pos in touches.iter_just_pressed().map(|t| t.position()) {
249+
for touch in touches.iter_just_pressed() {
226250
let (camera, transform) = *camera;
227-
let Some(world_pos) = viewport_to_world(pos, camera, transform) else {
251+
let Some(world_pos) = viewport_to_world(touch.position(), camera, transform) else {
228252
return;
229253
};
230-
for (button, mut state, transform) in &mut button {
254+
for (button, mut state, transform) in &mut buttons {
231255
if world_pos.xy().distance(transform.translation.xy()) < button.radius {
232256
commands.trigger(U::default());
233-
state.0 = true;
257+
state.touched = Some(touch.id());
258+
}
259+
}
260+
}
261+
}
262+
263+
fn handle_touch_release<'a, T>(mut buttons: Query<&mut ButtonState, With<T>>, touches: Res<Touches>)
264+
where
265+
T: Component + Send + Sync,
266+
{
267+
for released_id in touches.iter_just_released().map(|t| t.id()) {
268+
for mut state in &mut buttons {
269+
if let Some(id) = state.touched {
270+
if id == released_id {
271+
state.touched = None;
272+
}
234273
}
235274
}
236275
}
237276
}
238277

239278
fn handle_touch_toggle<'a, T, U: Default + Event>(
240279
camera: Single<(&Camera, &GlobalTransform)>,
241-
mut button: Query<(&CircleButton, &mut ButtonState, &Transform), With<T>>,
280+
mut button: Query<(&CircleButton, &mut ToggleState, &Transform), With<T>>,
242281
mut commands: Commands,
243282
touches: Res<Touches>,
244283
) where
@@ -330,7 +369,7 @@ fn draw_buttons(
330369
) {
331370
for (button, state, transform, mut col) in &mut buttons {
332371
painter.set_translation(transform.translation - 0.1 * Vec3::Z);
333-
if state.0 {
372+
if state.clicked || state.touched.is_some() {
334373
*col = TextColor(button.bg_color);
335374
painter.set_color(button.fg_color);
336375
} else {

solitaire-game/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,27 @@ use solitaire_solver::Board;
55
use crate::{
66
animation::PegAnimation,
77
board::{BoardPlugin, BoardPosition, PEG_RADIUS},
8+
buttons::Buttons,
89
fps_overlay::FpsOverlay,
910
hints::HintsPlugin,
1011
input::Input,
1112
solver::Solver,
1213
stats::StatsPlugin,
1314
status::StatusPlugin,
1415
total_progress::TotalProgressPlugin,
15-
undo::Buttons,
1616
window::MainWindow,
1717
};
1818

1919
mod animation;
2020
mod board;
21+
mod buttons;
2122
mod fps_overlay;
2223
mod hints;
2324
mod input;
2425
mod solver;
2526
mod stats;
2627
mod status;
2728
mod total_progress;
28-
mod undo;
2929
mod window;
3030

3131
#[bevy_main]

0 commit comments

Comments
 (0)