Updating handles from within Position Changed Callback

7 views (last 30 days)
Stephen
Stephen on 15 Jul 2014
Edited: Stephen on 17 Jul 2014
I have defined an impoint roi object inside of an axis. I've set up the impoint with a callback for position changed function, and in that function I change the position of a second impoint as follows:
function positionChanged(pos)
handles = guihandles;
pointMoved = gco; %moving point is currently selected object
...
kids = get(pointMoved,'Children');
kids2 = get(correspondingPoint,'Children');
set(kids2(1),'Position',get(kids(1),'Position'));
set(kids2(1),'String',get(kids(1),'String'));
set(kids2(2),'XData',get(kids(2),'XData'));
set(kids2(2),'YData',get(kids(2),'YData'));
set(kids2(3),'XData',get(kids(3),'XData'));
set(kids2(3),'YData',get(kids(3),'YData'));
I'm just trying to get correspondingPoint to have the same values and positions as the point generating the callback, and the above works pretty well for this. The problem is that upon moving or resizing my figure window, all of those set values (minus the 'String' property, for some reason) revert, and my second impoint goes back to the position it had before the callback.
  2 Comments
Stephen
Stephen on 16 Jul 2014
Hrm... now that I think about it you may be right, but I am not sure how I would go about getting that another way. I have an arbitrary number of points defined at runtime, so each of them would execute the same callback. The way MATLAB handles the interrupt I have no way of controlling the input arguments to see which point is responsible for the callback. Anyone have any ideas?

Sign in to comment.

Accepted Answer

Alfonso Nieto-Castanon
Alfonso Nieto-Castanon on 15 Jul 2014
Your figure might have a resizefcn callback that could be reverting those values. Check:
get(gcf,'resizefcn');
  7 Comments
Stephen
Stephen on 17 Jul 2014
Yes, that makes sense and works well! I tried it out on a copy of my code, and seems to do it. That's a neat trick to be able to cast varargin. Much appreciated! I was also able to hack my way through the problem as in the answer below, but this is much simpler.

Sign in to comment.

More Answers (1)

Stephen
Stephen on 17 Jul 2014
While I did not solve the problem, I did come up with a work-around which does what I need, in case anyone comes after me has the same issues. I've found that if you first change the position of an impoint object inside of the callback as done in the original question, and then go through and create new impoint objects in their place, the changed position is stable so long as you're careful to keep the handles.impoint array updated. Here is the code inside of the position changed callback which does that, by iterating through the handles.impoints array:
handles = guihandles;
for i = 1:length(handles.impoint)
currentPoint = handles.impoint(i);
kids = get(currentPoint,'children');
%save everything to put into new point
x = get(kids(3),'XData');
y = get(kids(3),'YData');
string = get(kids(1),'String');
axis = get(currentPoint,'parent');
userData = get(currentPoint,'UserData');
color = get(currentPoint,'children');
color = get(color(2),'Color');
%don't overwrite the currently moving point
if i == pointMovedIdx
continue;
end
%otherwise, remake the point
h = impoint(axis,x,y);
setString(h,string);
setColor(h,color);
%add the correct callback based on which axis it's in
if axis == handles.axFiltered
%it's in axFiltered
addNewPositionCallback(h,@positionChangedFiltered);
%get the double handle
han = get(handles.axFiltered,'children');
han = han(1);
else
%it's in axUnfiltered
addNewPositionCallback(h,@positionChangedUnfiltered);
han = get(handles.axUnfiltered,'children');
han = han(1);
end
set(han,'UserData',userData);
handles.impoint(i) = han;
delete(currentPoint);
end
  1 Comment
Stephen
Stephen on 17 Jul 2014
Also, see the answer above for a much simpler solution thanks to Alfonso!

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by