# How to have button's action repeat as long as the button remains pressed?

The widget below is just a toy that I put together so that I could ask this question.

DynamicModule[
{c = {0, 0}, a = 1, da = 0.1, digits},
digits = -Round[Log10[FractionalPart[da]]];
Manipulate[
Graphics[
GeometricTransformation[Rectangle[c - 1, c + 1],
RotationTransform[a, c]]
, ImageSize -> Small
, AspectRatio -> Automatic
, PlotRange -> Transpose[{c - 1.5, c + 1.5}]
]
, Row[{
InputField[
Dynamic[
ToString[
NumberForm[ a
, {Infinity, digits}
, ExponentFunction -> (Null &)
]
]
, If[StringMatchQ[#, FrontEndPrivateValidNumberRegex],
a = ToExpression[#]] &
]
, String
, ImageSize -> 50
]
, Spacer[10]
, Button["\[DownArrow]", a -= da]
, Spacer[5]
, Button["\[UpArrow]", a += da]
}]
]
]


The widget's intended functionality is to let the user

1. specify, via the input field, a "base point" value for the square's rotation angle (in radians); and then
2. perturb this value in small increments, up or down, by clicking on the buttons.

(The idea is to have the functionality of an "infinite slider".)

Currently, to perturb the value by more than a single increment, one must click the appropriate button repeatedly.

Q: How can I have the value of the angle (and the square's corresponding rotation) continue to be perturbed as long as the button remains pressed?

(I imagine that it may be necessary to throttle the updates, to prevent them from happenning too rapidly.)

EDIT

I should have made clear that, for the intended functionality, it is essential that the changes in the angle be immediately reflected in the square's current rotation. IOW, while a button remains pressed, not only should the angle's numeric value change, but also the square should rotate (visibly).

You may use EventHandler and CurrentValue["MouseButtons"].

For example, change your last Button to:

EventHandler[
Button["\[UpArrow]", Null],
{"MouseDown" :>
While[CurrentValue["MouseButtons"] != {}, a += da; Pause[.1]]},
Method -> "Queued"
]


Now clicking and press and holding will increment as requested.

Hope this helps.

• Thanks! How would I need to modify the code you showed so that the square rotates while the button is held down? (IOW, so that not just the input field is visibly updated while the button is pressed, but also the graphic.)
– kjo
May 12, 2017 at 21:29
• @kjo Wrap your GeometricTransformation in Dynamic. Graphics[ Dynamic[ GeometricTransformation[ ... ] ], ...]. May 13, 2017 at 11:35