Abort an EventHandler?
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}
]
There are a couple of issues.
- The floating-point arithmetic could result in a point close to (0, 0) without being equal to (0, 0). Use
Chop
. - The
Abort
happens afterpt
is updated inEventHandler
. 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.