MATLAB Answers

datacursormode overwrites keyPressFcn by setting in protective listeners. How can I automatically shut this off each time these listeners are enabled?

11 views (last 30 days)
Christopher Redwood
Christopher Redwood on 23 Oct 2012
Answered: Igor on 4 Jun 2016
For those who don't know, if you try to enable a keyPressFcn in a figure, it will override any keyPressFcn set in the figure handle anytime datacursormode, pan, rotate3d, or zoom are turned on. Next, it enables a listener which prevents further access to keyPressFcn.
Walter Roberson nicely came up with the fix to re-enable keyPressFcn functionality by disabling the listener, linked and copied below. However; it turns out you can easily break this fix by again turning on any of the interactive data tools (datacursormode, zoom, pan, rotate3d), which poses a large problem in my application which requires the user to explore the data. When these tools are turned back on, their default behavior resets the keyPressFcn.
I could use Roberson's fix if I had a way to monitor when the figure's keyPressFcn gets reset by the data tools. Unfortunately, I have no experience with programming event handlers.
If you have followed up to here, my questions are : Is there a way to monitor when the figure's keyPressFcn is modified? If so, how would I build an event handler to handle this event? If this is possible, the listener, when notified, could just reinsert Robinson's code.
< Robinson's Fix>
h = zoom(zfigh);
set(h, 'Enable', 'on');
hManager = uigetmodemanager(zfigh);
set(hManager.WindowListenerHandles,'Enable','off'); % zap the listeners
% with the listners turned off we can put in our own hook
set(zfigh, 'KeyPressFcn', newkeyhook );

Answers (2)

Igor on 4 Jun 2016
If anyone is still looking for a complete working example - I was unable to find any, so I’ve decided to write my own. Hope it would be helpful.

Walter Roberson
Walter Roberson on 23 Oct 2012
The above code is a shorter version of what I implemented. What I did was set the callback to a function that disables the listener and sets a second function as the callback. Then in the second function, when it is time to turn the function off, the second function sets the first function as the callback and turns the listeners back on. In this way, one of the two functions is always set as the callback.
Probably a single function with a persistent variable could be used instead.
If I recall, though, I was not using the figure tool menubar to enable or disable the tools. My graphics were mostly inside my main GUI, which had uicontrols, and as soon as you add a uicontrol to a figure, the figure menubar is disabled by default (see the figure 'Menubar' property for more on that.)
It is possible, but a nuisance, to overwrite the callbacks in the menubar uicontextmenu items.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!