11use 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 ) ]
6980struct 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
239278fn 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 {
0 commit comments