6
$\begingroup$

How do I stop an EventHandler? I'm trying to allow the user unlimited inputs on the arrow keys UNTIL certain conditions are met, and then stop the EventHandler and move on to something else. How can I accomplish this? I've tried:

EventHandler[
  content,
  {"LeftArrowKeyDown" :>  ({  action;   If[conditions, Abort[]];})
   "RightArrowKeyDown" :> ({  action;  If[conditions, Abort[]]; })
   "UpArrowKeyDown" :>  ({  action;   If[conditions, Abort[]]; })
   "DownArrowKeyDown" :> ({ action;  If[conditions, Abort[]];  })
}]

But Mathematica seems to ignore the Abort[] completely, though it will execute other commands within the If statements when the same conditions are met. What am I missing here??

Edit: Okay, my code was rather general and unclear. Here is a more concrete example of what I want:

pt = {0.5, 0.5};
EventHandler[
 Framed[Graphics[
   {{Red, Disk[Dynamic[pt], .1]}},
   PlotRange -> 1, Axes -> True
   ]],
 {
  "LeftArrowKeyDown" :> (
    pt -= {0.05,0};
    If[pt == {0, 0}, Abort[]]
    ),
  "RightArrowKeyDown" :> (
    pt +={0.05,0};
    If[pt == {0, 0}, Abort[]]
    ),
  "UpArrowKeyDown" :> (
    pt +={0,0.05};
    If[pt == {0, 0}, Abort[]]
    ),
  "DownArrowKeyDown" :> (
    pt -={0,0.05};
    If[pt == {0, 0}, Abort[]]
    )
  }
 ]

So, my goal is to allow unlimited movement around this plane by the Disk, until the user moves the Disk to the point (0,0), at which time I want Mathematica to stop allowing input and move on to a different task in the code.

$\endgroup$
5
  • $\begingroup$ Welcome to Mathematica.SE! 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Take the tour and check the faqs! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! $\endgroup$
    – user9660
    Commented Apr 13, 2016 at 17:22
  • $\begingroup$ I;m not quite sure what are you after. the action is take whether conditions are True or Note. Abort aborts only a specific evaluation and each event triggers another one. Do you want to disable an event completely after conditions are met? Or do you want to tak an action when conditions are True? Or maybe something different? $\endgroup$
    – Kuba
    Commented Apr 14, 2016 at 6:48
  • $\begingroup$ I want to disable any further events completely when 'conditions' are True. $\endgroup$ Commented Apr 14, 2016 at 14:39
  • $\begingroup$ What Operating System are you own? $\endgroup$
    – William
    Commented Apr 14, 2016 at 20:48
  • $\begingroup$ I am on Windows 7. $\endgroup$ Commented Apr 14, 2016 at 21:14

2 Answers 2

4
$\begingroup$

Shortly, use a SelectorPane and hide EventHandler as soon as the condition is met:

pt = {0, .05};

pane = "dynamic";

graphics = Framed[Graphics[
   {{Red, Disk[Dynamic[pt], .1]}}, PlotRange -> 1, Axes -> True]
];


eh = EventHandler[#,
    {
     "LeftArrowKeyDown" :> (pt -= {0.05, 0}; check@pt),
     "RightArrowKeyDown" :> (pt += {0.05, 0}; check@pt),
     "UpArrowKeyDown" :> (pt += {0, 0.05}; check@pt),
     "DownArrowKeyDown" :> (pt -= {0, 0.05}; check@pt)}
    ] &;


   (* Norm will be better as there some subtleties with =={0,0}*)
check[pts_] := If[Norm[pts] < .01, pane = "static"; FinishDynamic[];];

Column[{
  PaneSelector[
   {"dynamic" -> eh@graphics, "static" -> graphics},
   Dynamic@pane

   ],
  Dynamic@pane}
 ]

enter image description here

$\endgroup$
2
$\begingroup$

There are a couple of issues.

  1. The floating-point arithmetic could result in a point close to (0, 0) without being equal to (0, 0). Use Chop.
  2. The Abort happens after pt is updated in EventHandler . So sequence of events is
    • Press key.
    • Update to (0, 0) (actually, really close to (0, 0)).
    • Not (0, 0), so continue.
    • Press key again.
    • Update to not (0, 0).
    • Not (0, 0), so continue.

You need move zero check to the start of the EventHandler and use Chop post arithmetic to succeed in the check.

pt = {0.5, 0.5};
EventHandler[
 Framed[Graphics[{{Red, Disk[Dynamic[pt], .1]}}, PlotRange -> 1, 
   Axes -> True]], {
  "LeftArrowKeyDown" :> (If[pt == {0, 0}, Print["Move on"]; Abort[]]; 
     pt -= {0.05, 0}; pt = Chop /@ pt; ),
  "RightArrowKeyDown" :> (If[pt == {0, 0}, Print["Move on"]; Abort[]]; 
     pt += {0.05, 0}; pt = Chop /@ pt;),
  "UpArrowKeyDown" :> (If[pt == {0, 0}, Print["Move on"]; Abort[]]; 
     pt += {0, 0.05}; pt = Chop /@ pt; ),
  "DownArrowKeyDown" :> (If[pt == {0, 0}, Print["Move on"]; Abort[]]; 
     pt -= {0, 0.05}; pt = Chop /@ pt;)}]

Hope this helps.

$\endgroup$

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.