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$
  • $\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 Apr 13 '16 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 Apr 14 '16 at 6:48
  • $\begingroup$ I want to disable any further events completely when 'conditions' are True. $\endgroup$ – incredi_imp Apr 14 '16 at 14:39
  • $\begingroup$ What Operating System are you own? $\endgroup$ – William Apr 14 '16 at 20:48
  • $\begingroup$ I am on Windows 7. $\endgroup$ – incredi_imp Apr 14 '16 at 21:14
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, privacy policy and cookie policy

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