5
$\begingroup$

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[#, FrontEnd`Private`ValidNumberRegex],
              a = ToExpression[#]] &
       ]
       , String
       , ImageSize -> 50
      ]
    , Spacer[10]
    , Button["\[DownArrow]", a -= da]
    , Spacer[5]
    , Button["\[UpArrow]", a += da]
    }]
  ]
]

Mathematica graphics


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).

$\endgroup$

1 Answer 1

5
$\begingroup$

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.

$\endgroup$
2
  • $\begingroup$ 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.) $\endgroup$
    – kjo
    Commented May 12, 2017 at 21:29
  • $\begingroup$ @kjo Wrap your GeometricTransformation in Dynamic. Graphics[ Dynamic[ GeometricTransformation[ ... ] ], ...]. $\endgroup$
    – Edmund
    Commented May 13, 2017 at 11:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.