@@ -73,6 +73,11 @@ class FlipInput(Widget, Control):
73
73
direction, set `False` for arrows in the vertical direction (default = `True`)
74
74
:param float animation_time: duration for the animation during flipping between
75
75
values, in seconds (default is 0.4 seconds), set to 0.0 or `None` for no animation.
76
+ :param float cool_down: minimum duration between activations of the widget with a
77
+ continuous pressing, this can be used to reduce the chance of accidental multiple
78
+ activations, in seconds (default is 0.0 seconds, no delay). Set to -1.0 to require
79
+ the button be released and pressed again for activation (Note: This requires calling
80
+ the ``released`` function prior to the next call to ``selected``.)
76
81
77
82
"""
78
83
@@ -94,6 +99,7 @@ def __init__(
94
99
alt_touch_padding = 0 , # touch padding on the non-arrow sides of the Widget
95
100
horizontal = True ,
96
101
animation_time = None ,
102
+ cool_down = 0.0 ,
97
103
** kwargs ,
98
104
):
99
105
@@ -124,6 +130,9 @@ def __init__(
124
130
self ._display = display
125
131
126
132
self ._animation_time = animation_time
133
+ self ._cool_down = cool_down
134
+ self ._last_pressed = time .monotonic ()
135
+ self ._pressed = False # state variable
127
136
128
137
# Find the maximum bounding box of the text and determine the
129
138
# baseline (x,y) start point (top, left)
@@ -412,6 +421,15 @@ def _update_value(self, new_value, animate=True):
412
421
self ._display .auto_refresh = True
413
422
self ._update_position () # call Widget superclass function to reposition
414
423
424
+ def _ok_to_change (self ): # checks state variable and timers to determine
425
+ # if an update is allowed
426
+ if self ._cool_down < 0 : # if cool_down is negative, require ``released``
427
+ # to be called before next change
428
+ return not self ._pressed
429
+ if (time .monotonic () - self ._last_pressed ) < self ._cool_down :
430
+ return False # cool_down time has not transpired
431
+ return True
432
+
415
433
def contains (self , touch_point ): # overrides, then calls Control.contains(x,y)
416
434
"""Returns True if the touch_point is within the widget's touch_boundary."""
417
435
@@ -429,34 +447,50 @@ def contains(self, touch_point): # overrides, then calls Control.contains(x,y)
429
447
return super ().contains ((touch_x , touch_y , 0 ))
430
448
431
449
def selected (self , touch_point ):
432
- """Response function when Control is selected. Increases value when upper half is pressed
433
- and decreases value when lower half is pressed."""
450
+ """Response function when the Control is selected. Increases value when upper half
451
+ is pressed and decreases value when lower half is pressed."""
434
452
435
453
# Adjust for local position of the widget using self.x and self.y
436
454
437
- t_b = self .touch_boundary
455
+ if self ._ok_to_change ():
456
+ t_b = self .touch_boundary
438
457
439
- if self ._horizontal :
440
- if (
441
- t_b [0 ] <= (touch_point [0 ] - self .x ) < (t_b [0 ] + t_b [2 ] // 2 )
442
- ): # in left half of touch_boundary
443
- self .value = self .value - 1
458
+ if self ._horizontal :
459
+ if (
460
+ t_b [0 ] <= (touch_point [0 ] - self .x ) < (t_b [0 ] + t_b [2 ] // 2 )
461
+ ): # in left half of touch_boundary
462
+ self .value = self .value - 1
444
463
445
- elif (
446
- (t_b [0 ] + t_b [2 ] // 2 ) <= (touch_point [0 ] - self .x ) <= (t_b [0 ] + t_b [2 ])
447
- ): # in right half of touch_boundary
448
- self .value = self .value + 1
464
+ elif (
465
+ (t_b [0 ] + t_b [2 ] // 2 )
466
+ <= (touch_point [0 ] - self .x )
467
+ <= (t_b [0 ] + t_b [2 ])
468
+ ): # in right half of touch_boundary
469
+ self .value = self .value + 1
449
470
450
- else :
451
- if (
452
- t_b [1 ] <= (touch_point [1 ] - self .y ) < (t_b [1 ] + t_b [3 ] // 2 )
453
- ): # in upper half of touch_boundary
454
- self .value = self .value + 1
455
-
456
- elif (
457
- (t_b [1 ] + t_b [3 ] // 2 ) <= (touch_point [1 ] - self .y ) <= (t_b [1 ] + t_b [3 ])
458
- ): # in lower half of touch_boundary
459
- self .value = self .value - 1
471
+ else :
472
+ if (
473
+ t_b [1 ] <= (touch_point [1 ] - self .y ) < (t_b [1 ] + t_b [3 ] // 2 )
474
+ ): # in upper half of touch_boundary
475
+ self .value = self .value + 1
476
+
477
+ elif (
478
+ (t_b [1 ] + t_b [3 ] // 2 )
479
+ <= (touch_point [1 ] - self .y )
480
+ <= (t_b [1 ] + t_b [3 ])
481
+ ): # in lower half of touch_boundary
482
+ self .value = self .value - 1
483
+
484
+ self ._pressed = True # update the state variable
485
+ self ._last_pressed = (
486
+ time .monotonic ()
487
+ ) # value changed, so update cool_down timer
488
+
489
+ def released (self ):
490
+ """Response function when the Control is released. Resets the state variables
491
+ for handling situation when ``cool_down`` is < 0 that requires `released()` before
492
+ reacting another another `selected()`."""
493
+ self ._pressed = False
460
494
461
495
@property
462
496
def value (self ):
0 commit comments