MATLAB: Rotate3d and ButtonDownFCN simultaneously active for two separate axes

3d rotationguirotate3d

Hi all,
What I would like to accomplish is: 1. Have one figure with two axes ax1 and ax2. 2. In ax1 the 3D rotation should be active. 3. In ax2 an image will be shown, and ButtonDownFCN should be called when clicked.
Example:
%%%%%%%%%%%%%%%%%%%%
ax1 = subplot(1,2,1);
surf(peaks);
h = rotate3d;
h.Enable = 'on';
ax2 = subplot(1,2,2);
I = imshow(rand(200,200),[]);
setAllowAxesRotate(h,ax2,false);
set(I,'ButtonDownFCN','disp(''clicked'')')
%%%%%%%%%%%%%%%%%%%%%%%
However, this does not work. Is it possible to somehow call ButtonDownFCN at a click in the axes that does not have 3D-rotation on?
Best, Patrik

Best Answer

Patrik - you could try using the rotate3d filter callback to decide whether to allow the rotation to occur, or to allow the object's ButtonDownFcn to be invoked instead.
Try the following (which is the same as your code except for the last line added)
close all;
ax1 = subplot(1,2,1);
surf(peaks);
h = rotate3d;
h.Enable = 'on';
ax2 = subplot(1,2,2);
I = imshow(rand(200,200),[]);
setAllowAxesRotate(h,ax2,false);
set(I,'ButtonDownFCN','disp(''clicked'')');
set(h,'ButtonDownFilter',@myRotateFilter);
where myRotateFilter is defined as
function [disallowRotation] = myRotateFilter(obj,eventdata)
disallowRotation = false;
% if a ButtonDownFcn has been defined for the object, then use that
if isfield(get(obj),'ButtonDownFcn')
disallowRotation = ~isempty(get(obj,'ButtonDownFcn'));
end
In the above function, if the object to be rotated (so either the surf object or the image, from your example) has its ButtonDownFcn defined, then use that instead (so disallowRotation is set to true) of doing the rotation.
Running the above code on R2014a and OS X 10.8.5, I could rotate the image on the left, and observe the clicked message in the Command Window whenever I clicked on the image on the right.