Bizarre Behavior of WindowButtonMotionFcn, UIAxes in UIFigure when axis set to 'equal'.

1 view (last 30 days)
When converting an old program using figure and axes to use UIFigure and UIAxes, I was seeing very poor performance in one particular operation: dragging a rectangle around on an Image created with imagesc. I boiled it all down to the following example:
classdef MouseDragProblem < handle
properties (Access = private)
%UI elements
mainFigure
ax
targetRectangle
%UI State
trackingMouse
clickPoint
end
methods (Access = public)
function this = MouseDragProblem()
this.mainFigure = uifigure();
this.ax = uiaxes(this.mainFigure);
this.ax.XLim=[0 100];
this.ax.YLim=[0 100];
% axis(this.ax,'equal'); %Uncomment me
imagesc(this.ax,rand([100 100]));
this.targetRectangle = rectangle(this.ax, 'Position', [0 0 25 25]);
this.targetRectangle.Parent = this.ax;
this.targetRectangle.FaceColor = [1 0 0 .25];
this.mainFigure.WindowButtonUpFcn = @this.stopMouseTracking;
this.targetRectangle.ButtonDownFcn = @this.startMouseTracking;
end
end
methods (Access = private)
function startMouseTracking(this, ~ ,~)
%Mouse tracking begins when the user clicks inside the
%rectangle
if this.trackingMouse
return;
end
this.mainFigure.WindowButtonMotionFcn = @this.handleDragRectangle;
this.trackingMouse = true;
this.clickPoint = this.ax.CurrentPoint;
end
function stopMouseTracking(this, ~, ~)
%Mouse tracking ends when the user releases the mouse button
if this.trackingMouse
this.trackingMouse = false;
end
end
function handleDragRectangle(this, src, ~)
%Updates the display of the highlight rectangle as the user
%drags it around.
seltype = src.SelectionType;
if strcmp(seltype, 'normal')
if this.trackingMouse
%the point where drag operation began
pSrc = this.clickPoint;
xSrc = pSrc(1,1);
ySrc = pSrc(1,2);
%the current pointer location
pDst = this.ax.CurrentPoint;
xDst = pDst(1,1);
yDst = pDst(1,2);
%calculate the distance moved in X and Y
xMove = xDst - xSrc;
yMove = yDst - ySrc;
%the current rectangle coordinates
rPos = this.targetRectangle.Position;
rX = rPos(1);
rY = rPos(2);
w = rPos(3);
h = rPos(4);
%Calculate the distance from the drag start position to the
%rectangle origin
xOff = xSrc - rX;
yOff = ySrc - rY;
%calculate the new rectangle position
xNew = xSrc + xMove - xOff;
yNew = ySrc + yMove - yOff;
%Reposition the rectangle
this.targetRectangle.Position = [xNew, yNew, w, h];
%make the current destination point the new source point
this.clickPoint = pDst;
end
end
end
end
end
If you run the code as-is, all is well. You can click the rectangle and drag it around with no problem. If you uncomment the line that sets the uiaxes to 'equal', dragging is now like moving through molasses. If you quickly move in circles, you can get 5 or six laps 'ahead' of the rectangle. Needless to say, this makes for a miserable user experience.
Of the four possible combinations of Figure, UIFigure and Axes and UIAxes, only UIFigure/UIAxes behaves this way.
I'm hoping that I've just missed one or more UIFigure/UIAxes axis properties that need to be tweaked.
If anyone has any insight, your assistance would be appreciated.

Answers (0)

Categories

Find more on Develop uifigure-Based Apps in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!