Is it possible to use multiple callbacks in the WindowButtonMotionFcn? - matlab

I created a class which adds functionality to a figure on construction. This class creates a listener for the WindowMouseMotion event; however, to get this event to fire I had to add a dummy callback function for the figure's WindowButtonMotionFcn property. I first check if this property is already populated. If it isn't then I set it to a dummy callback function that does nothing.
Instead of checking if the property is already set or not, can I simply add this dummy callback to any existing callbacks? Is it possible for a callback property to call multiple functions?
EDIT
When using the handle.listener approach to handle the WindowButtonMotionEvent event given below, be sure to use eventdata.CurrentPoint to access the current mouse position. The CurrentPoint property of the figure does not get updated before handling the WindowButtonMotionEvent event in this manner.

A related article can be found on Yair Altman's Undocumented MATLAB blog, from guest blogger Matt Whitaker. What you are alluding to is callback chaining, and quoting from the blog:
Frankly, having written code
previously that handles callback
chaining, I would rather poke myself
in the eye with a fork!
Luckily, there appears to be an alternative solution in that article. Using a snippet from the code posted there, I was able to get a function to execute on mouse movement without having to set the 'WindowButtonMotionFcn'. I added a listener to the current figure like so:
myListener = handle.listener(gcf,'WindowButtonMotionEvent',...
#(hSource,eventData) disp('hello'));
And the message hello was displayed when I moved the mouse in the window.

You can do this via cellfun and feval, as answered on Mathworks site: http://www.mathworks.com/matlabcentral/answers/10664-multiple-callback-functions
obj = uicontrol(...,'style','popupmenu',...
'Callback', #(h,e)(cellfun(#(x)feval(x,h,e), ...
{#(h,e)this.myfunc(h), ...
#(h,e)this.myfunc2(h), ...
#(h,e)this.myfunc2(h)}))
Note that the callback is set to an anonymous function using cellfun to evaluate each handler.

Related

how to identify a callback or link a callback to a previous function?

just started learning and bumped into this callback thing, not sure I fully follows this example below, callback is an argument for function inputName, but how is it being linked to the previous function sayHello? I think I missed the logic flow here>, is it possible there are two callbacks? how to decide which one to refer to then, many thanks.
enter image description here

In Matlab, how to call GUI callback functions without the GUI?

I am not a GUI programmer, as will become obvious. If anything, I'm trying to unmake a GUI. I am using a program called art (found here, if it's useful to see) that generates figures and variables that I would like to save. You can call art from a batch script and make it read a config file for its inputs, which is what I'm doing, but you have to manually generate and save much of its output (variables and figures) in the GUI. I'd love to automate this process, but I am really struggling.
I think the core of my issue would be solved if I knew how to force the callback functions to be called. For instance, there is a function in art showCorr_Callback(hObject, eventdata, handles) (which is governed by a radio button in the GUI). It has a test condition to execute:
if (get(handles.showCorr,'Value') == get(handles.showCorr,'Max'))
I've tried inserting
mx = get(handles.showCorr,'Max'))
setappdata(handles.showCorr,'Value', mx)
into a function I know executes, the opening function, function art_OpeningFcn(hObject, eventdata, handles, varargin). That doesn't seem to have any effect. If I knew how to make the callback functions execute, perhaps I could insert the code that saves the figure into the functions. Somewhere in Matlab's GUI scripts there must be something that is continually testing for a change in state in the GUI. Where is that thing? How can I fool it into thinking a radio button has been pressed?
Thanks for your help, and please let me know if I need to provide more information.
First of all, if you want to set the Value of handles.showCorr, you won't use setappdata as that just stores arbitrary data (by key/value pair) into the graphics object. You actually want to set the Value property.
set(handles.showCorr, 'Value', get(handles.showCorr, 'Max'))
This should trigger any callbacks that are assigned to handles.showCorr.
If, for some reason this doesn't trigger the callback, you can always trigger it manually. If you already know the callback, you can call it explicitly.
showCorr_Callback(hObject, eventdata, handles);

Check if editbox is active (and evaluate WindowKeyPressFcn only if its not) in matlab

I would like to be able to test whether given edit box (uicontrol with 'style' set to 'edit') is being used at the moment (whether the cursor is inside that box / the edit box has focus).
Unfortunatelly the 'Selected' property of the editbox seems to be 'off' all the time and it's use is discouraged by MathWorks
I am open to Java solutions (but I have not tried any yet).
Background
My broader goal is to activate specific functions in response to keys pressed by the user (keyboard shortcuts) but only if the user is not typing these letters into an edit box.
I evaluate keyboard shortcuts with 'WindowKeyPressFcn' callback. I thought about using editbox's 'KeyPressFcn' callback to block 'WindowKeyPressFcn' (by passing something through setappdata or 'UserData') but it seems that 'WindowKeyPressFcn' is always evaluated first.
So now I'm trying to detect whether the editbox is in use some other way.
Since MATLAB uicontrols have underlying Java Swing GUI controls, I can think of two "Java solutions":
Associate a FocusGainedCallback with the Java object of editbox (using FindJObj - see below) (and possibly other UI elements), and update some handle \ persistent \ global variable from this function to hold the currently focused object handle. This type of callback is mentioned in an UndocumentMatlab article on uicontrol callbacks.
You should be able to use Java'sisFocusOwner() method on the underlying java object of your editbox (this method is mentioned in the Java documentation of the focus subsystem).
Note: the simplest way to get the java object is using the utility FindJObj that is briefly described here.
An alternative, much simpler method, would be to use the WindowKeyReleaseFcn callback of the GUI figure. This gets fired after the release of the keystroke, hence it gets executed after the gco gets the updated value of the currently focused uicontrol. The following check in the beginning of the WindowKeyReleaseFcn can determine if the keystroke comes from the edit box:
function figure1_WindowKeyReleaseFcn(hObject, eventdata, handles)
% gco is already updated by the time we are here to reflect the uicontrol
% which is in focus
if isequal(gco, handles.hEditBox) % Keystroke comes from the edit box
return
end
% Keystroke does not come from the edit box -- Do something here...

gtk.fixed layout laid out events?

I have a gtk.Fixed. I move components inside it around using:
myFixed.move( myEventBox, new_x, new_y )
What event do I listen for to know when myEventBox has been rendered at its new position?
Do I connect to the fixed or the eventbox?
MORE INFO:
I need this information so I know when it is safe to queue a video under the eventbox... if I do it too soon (e.g. right after calling myFixed.move) I can see the glitch. Currently getting around this with a gobject.idle_add.
To be honest, I am not aware of any such event. The object should move immediately and redraw the screen, but I don't think any signal is emitted when that happens.
The PyGTK documentation is very comprehensive, and it will list all of the functions and events of every object in the library. In searching (through both the gtk.Container (for fixed) and gtk.Widget (for fixed and eventbox) signal lists, I can't find any such event. The closest thing is an "add" signal in gtk.Container, but I don't think that's what you're looking for.
If the object is not moving, please post your code, because there is probably a subtle error.
If the object is moving just fine and you just want the event/signal, you may have to simulate it yourself. Write the function you want to be called as soon as the object is moved in a function (def) inside "__ init __", and then call that function in code in the line right after "myFixed.move".

MATLAB: Perform callback on variable change?

I am trying to build a GUI with several tabs, using uitabpanel() found at http://www.mathworks.com/matlabcentral/fileexchange/11546 . I would like to resize the GUI based on the currently opened tab; this is available with uitabpanel.SelectedItem.
Basically I would like to build a callback in order to monitor uitabpanel.SelectedItem - when this variable changes, the GUI window should resize appropriately. Generally speaking, I am looking for a way to monitor a variable and execute a callback when the variable changes value.
Is this possible? How would I go about doing this?
Thanks!
I don't have a MATLAB in front of me right now, but if it is implemented as a property -- and as far as I can tell from a quick look at the code, it is -- you can use addlistener function and provide a callback function for it.
addlistener(hTab,'SelectedItem','PostSet',#(s,e)disp('SelectedItem changed'))
I'm not familiar with uitab from the file exchange. However, if it's build upon the built-in uitab, then there should be a selectionChangeCallback or selectionChangeFcn property (depending on your Matlab version). Specify a function for this callback property, and you have a way to execute a function whenever the selection changes.
If that's not possible, the only other way to monitor a variable change (if you can't somehow use objects and set methods) is to use a TIMER OBJECT that periodically polls the value of the variable.
EDIT Since the FEX uitab is based on uipanel, the callback you're looking for is most likely ButtonDownFcn. Before you change it, make sure that it's not used by the uitab function, otherwise, you will want to edit that function.