1
1
//! This example shows how to create a node with a shadow and adjust its settings interactively.
2
2
3
+ use bevy:: time:: Time ;
3
4
use bevy:: { color:: palettes:: css:: * , prelude:: * , winit:: WinitSettings } ;
4
5
5
6
const NORMAL_BUTTON : Color = Color :: srgb ( 0.15 , 0.15 , 0.15 ) ;
@@ -61,7 +62,7 @@ struct ShadowSettings {
61
62
#[ derive( Component ) ]
62
63
struct ShadowNode ;
63
64
64
- #[ derive( Component ) ]
65
+ #[ derive( Component , PartialEq , Clone , Copy ) ]
65
66
enum SettingsButton {
66
67
XOffsetInc ,
67
68
XOffsetDec ,
@@ -81,12 +82,20 @@ enum SettingsButton {
81
82
#[ derive( Component ) ]
82
83
struct ValueLabel ( String ) ;
83
84
85
+ #[ derive( Resource , Default ) ]
86
+ struct HeldButton {
87
+ button : Option < SettingsButton > ,
88
+ pressed_at : Option < f64 > ,
89
+ last_repeat : Option < f64 > ,
90
+ }
91
+
84
92
fn main ( ) {
85
93
App :: new ( )
86
94
. add_plugins ( DefaultPlugins )
87
- . insert_resource ( WinitSettings :: desktop_app ( ) )
95
+ . insert_resource ( WinitSettings :: default ( ) )
88
96
. insert_resource ( SHADOW_DEFAULT_SETTINGS )
89
97
. insert_resource ( SHAPE_DEFAULT_SETTINGS )
98
+ . insert_resource ( HeldButton :: default ( ) )
90
99
. add_systems ( Startup , setup)
91
100
. add_systems (
92
101
Update ,
@@ -95,6 +104,7 @@ fn main() {
95
104
button_color_system,
96
105
update_shape,
97
106
update_shadow,
107
+ button_repeat_system,
98
108
) ,
99
109
)
100
110
. run ( ) ;
@@ -501,47 +511,91 @@ fn button_system(
501
511
> ,
502
512
mut shadow : ResMut < ShadowSettings > ,
503
513
mut shape : ResMut < ShapeSettings > ,
514
+ mut held : ResMut < HeldButton > ,
515
+ time : Res < Time > ,
504
516
) {
517
+ let now = time. elapsed_secs_f64 ( ) ;
505
518
for ( interaction, btn) in & mut interaction_query {
506
- if * interaction == Interaction :: Pressed {
507
- match btn {
508
- SettingsButton :: XOffsetInc => shadow. x_offset += 1.0 ,
509
- SettingsButton :: XOffsetDec => shadow. x_offset -= 1.0 ,
510
- SettingsButton :: YOffsetInc => shadow. y_offset += 1.0 ,
511
- SettingsButton :: YOffsetDec => shadow. y_offset -= 1.0 ,
512
- SettingsButton :: BlurInc => shadow. blur = ( shadow. blur + 1.0 ) . max ( 0.0 ) ,
513
- SettingsButton :: BlurDec => shadow. blur = ( shadow. blur - 1.0 ) . max ( 0.0 ) ,
514
- SettingsButton :: SpreadInc => shadow. spread += 1.0 ,
515
- SettingsButton :: SpreadDec => shadow. spread -= 1.0 ,
516
- SettingsButton :: CountInc => {
517
- if shadow. count < 3 {
518
- shadow. count += 1 ;
519
- }
520
- }
521
- SettingsButton :: CountDec => {
522
- if shadow. count > 1 {
523
- shadow. count -= 1 ;
524
- }
525
- }
526
- SettingsButton :: ShapePrev => {
527
- if shape. index == 0 {
528
- shape. index = SHAPES . len ( ) - 1 ;
529
- } else {
530
- shape. index -= 1 ;
531
- }
532
- }
533
- SettingsButton :: ShapeNext => {
534
- shape. index = ( shape. index + 1 ) % SHAPES . len ( ) ;
535
- }
536
- SettingsButton :: Reset => {
537
- * shape = SHAPE_DEFAULT_SETTINGS ;
538
- * shadow = SHADOW_DEFAULT_SETTINGS ;
519
+ match * interaction {
520
+ Interaction :: Pressed => {
521
+ trigger_button_action ( btn, & mut * shadow, & mut * shape) ;
522
+ held. button = Some ( * btn) ;
523
+ held. pressed_at = Some ( now) ;
524
+ held. last_repeat = Some ( now) ;
525
+ }
526
+ Interaction :: None | Interaction :: Hovered => {
527
+ if held. button == Some ( * btn) {
528
+ held. button = None ;
529
+ held. pressed_at = None ;
530
+ held. last_repeat = None ;
539
531
}
540
532
}
541
533
}
542
534
}
543
535
}
544
536
537
+ fn trigger_button_action (
538
+ btn : & SettingsButton ,
539
+ shadow : & mut ShadowSettings ,
540
+ shape : & mut ShapeSettings ,
541
+ ) {
542
+ match btn {
543
+ SettingsButton :: XOffsetInc => shadow. x_offset += 1.0 ,
544
+ SettingsButton :: XOffsetDec => shadow. x_offset -= 1.0 ,
545
+ SettingsButton :: YOffsetInc => shadow. y_offset += 1.0 ,
546
+ SettingsButton :: YOffsetDec => shadow. y_offset -= 1.0 ,
547
+ SettingsButton :: BlurInc => shadow. blur = ( shadow. blur + 1.0 ) . max ( 0.0 ) ,
548
+ SettingsButton :: BlurDec => shadow. blur = ( shadow. blur - 1.0 ) . max ( 0.0 ) ,
549
+ SettingsButton :: SpreadInc => shadow. spread += 1.0 ,
550
+ SettingsButton :: SpreadDec => shadow. spread -= 1.0 ,
551
+ SettingsButton :: CountInc => {
552
+ if shadow. count < 3 {
553
+ shadow. count += 1 ;
554
+ }
555
+ }
556
+ SettingsButton :: CountDec => {
557
+ if shadow. count > 1 {
558
+ shadow. count -= 1 ;
559
+ }
560
+ }
561
+ SettingsButton :: ShapePrev => {
562
+ if shape. index == 0 {
563
+ shape. index = SHAPES . len ( ) - 1 ;
564
+ } else {
565
+ shape. index -= 1 ;
566
+ }
567
+ }
568
+ SettingsButton :: ShapeNext => {
569
+ shape. index = ( shape. index + 1 ) % SHAPES . len ( ) ;
570
+ }
571
+ SettingsButton :: Reset => {
572
+ * shape = SHAPE_DEFAULT_SETTINGS ;
573
+ * shadow = SHADOW_DEFAULT_SETTINGS ;
574
+ }
575
+ }
576
+ }
577
+
578
+ // System to repeat button action while held
579
+ fn button_repeat_system (
580
+ time : Res < Time > ,
581
+ mut held : ResMut < HeldButton > ,
582
+ mut shadow : ResMut < ShadowSettings > ,
583
+ mut shape : ResMut < ShapeSettings > ,
584
+ ) {
585
+ const INITIAL_DELAY : f64 = 0.15 ;
586
+ const REPEAT_RATE : f64 = 0.08 ;
587
+ if let ( Some ( btn) , Some ( pressed_at) ) = ( held. button , held. pressed_at ) {
588
+ let now = time. elapsed_secs_f64 ( ) ;
589
+ let since_pressed = now - pressed_at;
590
+ let last_repeat = held. last_repeat . unwrap_or ( pressed_at) ;
591
+ let since_last = now - last_repeat;
592
+ if since_pressed > INITIAL_DELAY && since_last > REPEAT_RATE {
593
+ trigger_button_action ( & btn, & mut * shadow, & mut * shape) ;
594
+ held. last_repeat = Some ( now) ;
595
+ }
596
+ }
597
+ }
598
+
545
599
// Changes color of button on hover and on pressed
546
600
fn button_color_system (
547
601
mut query : Query <
0 commit comments