Matlab contains several well-documented functions and properties dealing with the mouse pointer. However, for some reason, some very-useful functions have remained undocumented and unsupported despite having a very long history (as far back as Matlab 6, a decade ago).
getptr, setptr, moveptr and overobj are all semi-documented functions (help section available, but online doc and official support not) which are used for internal Matlab purposes and relate to the mouse pointer. All these files are pure-Matlab non-Java files, which can be edited and modified. getptr and setptr (%Matlabroot\toolbox\matlab\uitools\getptr.m and setptr.m) access the pointer shape for a figure; moveptr (%Matlabroot\toolbox\shared\controllib\moveptr.m) moves the pointer across the screen; overobj (%Matlabroot\toolbox\matlab\uitools\overobj.m) determines which figure component is currently beneath the pointer.
getptr and setptr
While undocumented Java code is needed for setting component-specific pointer shapes, figure-wide shapes can be set using pure-Matlab. Setting the mouse pointer shape is normally achieved by modifying the figure’s Pointer property, which is fully documented. The following pointer shapes are supported: ‘arrow’ (the default Matlab pointer), ‘crosshair’, ‘fullcrosshair’ (used for ginput), ‘ibeam’, ‘watch’, ‘topl’, ‘topr’, ‘botl’, ‘botr’, ‘left’, ‘top’, ‘right’, ‘bottom’, ‘circle’, ‘cross’, ‘fleur’, and ‘custom’. For example:
set(hFig, 'Pointer', 'crosshair');
Using setptr enables access to a far greater variety of pointer shapes, in addition to all the standard shapes above: ‘hand’, ‘hand1′, ‘hand2′, ‘closedhand’, ‘glass’, ‘glassplus’, ‘glassminus’, ‘lrdrag’, ‘ldrag’, ‘rdrag’, ‘uddrag’, ‘udrag’, ‘ddrag’, ‘add’, ‘addzero’, ‘addpole’, ‘eraser’, ‘help’, ‘modifiedfleur’, ‘datacursor’, and ‘rotate’. It also has a few entirely-undocumented shapes: ‘forbidden’, and ‘file’ (which expects a cursor data filepath as the following argument):
setptr(gcf, 'hand'); setptr(gcf, 'file', 'my137byteFile.data');
getptr returns a cell array of parameter name/value pairs that can be stored and later used to restore the pointer shape for a specified figure:
ptr = getptr(gcf); % do some stuff... set(gcf, ptr{:});
moveptr
moveptr is used to move the mouse pointer programmatically across a specific plot axes. This function is poorly and incorrectly documented and contains quite a few bugs (as of R2008b). However, with minor fixes and slight attention to usage, it can be quite useful.
The regular and fully documented/supported method of moving the mouse pointer across the screen is by modifying the root (0) handle’s PointerLocation property. In many cases we may wish to programmatically move the pointer from to a specific location in a plot axes. This can be done of course by computing the figure’s dimensions and position in screen pixel coordinates, and the internal figure components dimensions/position within the figure, and their internal components and so on, not forgetting to translate data or normalized coordinates into screen pixel units, and taking care of logarithmic and reverse axes. After adding all these up, and assuming we’ve made no mistake in the computation (no easy task), we can now set the root handle’s PointerLocation property.
Comes moveptr to the rescue:
moveptr accepts a handle(hAxes) as first parameter (note that handle(hAxes) must be passed, not hAxes!), and one of the following; either ‘init’ to initialize the move (creating a transformation from local axes data units to screen pixels), or ‘move’ followed by X,Y (axes data units) to actually move the mouse pointer. X and Y may well be outside the axes boundaries:
moveptr(handle(gca),'init'); moveptr(handle(gca),'move',-5,7); % so easy
moveptr is only available in Matlab 7, not Matlab 6. moveptr also has a bug/limitation (fixed in R2008a) in that it expects the supplied axes to be a direct child of the figure. Finally, it accepts handle(hAxes) as first parameter – not the regular numeric hAxes handle as its help section would have us believe. These may not of course be the case in a more general case. Note that R2008a’s fix for the direct-figure-child limitation, using hgconvertunits (another semi-documented function), is incompatible with Matlab 6, which did not have this function. The fix for all these issues, which accepts both hAxes and handle(hAxes), removes the direct-figure-child limitation and also works on Matlab 6, is outlined below:
%% Moveptr replacement for Matlab 6 compatibility function moveptr(hAx, x, y) % Compute normalized axis coordinates NormX = getNormCoord(hAx, 'x', x); NormY = getNormCoord(hAx, 'y', y); % Compute the new coordinates in screen units Transform = axis2Screen(hAx); NewLoc = Transform(1:2) + Transform(3:4) .* [NormX NormY]; % Move the pointer set(0,'PointerLocation',NewLoc); %end % moveptr %% Get normalized axis coordinates function normCoord = getNormCoord(hAx, axName, curPos) limits = get(hAx, [axName 'Lim']); if strcmpi(get(hAx,[axName 'Scale']), 'log') normCoord = (log2(curPos) - log2(limits(1))) /diff(log2(limits)); else normCoord = (curPos-limits(1)) / diff(limits); end %end % getNormCoord %% Axis to screen coordinate transformation function T = axis2Screen(ax) % computes a coordinate transformation T = [xo,yo,rx,ry] that % relates normalized axes coordinates [xa,ya] of point [xo,yo] % to its screen coordinate [xs,ys] (in the root units) by: % xs = xo + rx * xa % ys = yo + ry * ya % Note: this is a modified internal function within moveptr() % Get axes normalized position in figure T = getPos(ax,'normalized'); % Loop all the way up the hierarchy to the root % Note: this fixes a bug in Matlab 7's moveptr implementation parent = get(ax,'Parent'); while ~isempty(parent) % Transform normalized axis coords -> parent coords if isequal(parent,0) parentPos = get(0,'ScreenSize'); % Save screen units else parentPos = getPos(parent, 'normalized'); % Norm units end T(1:2) = parentPos(1:2) + parentPos(3:4) .* T(1:2); T(3:4) = parentPos(3:4) .* T(3:4); parent = get(parent,'Parent'); end %end % axis2Screen
overobj and hittest
overobj is a related semi-documented function. It returns a handle to the first visible element beneath the mouse pointer that has visible handles (i.e., can be found with findobj , as opposed to hidden handles that can only be found using findall). The mandatory Type argument specifies the requested handle’s Type property value.
There are several overobj usage samples in CSSM. Here is an example for modifying the mouse cursor over axes:
% Modify mouse pointer over axes hAxes = overobj('axes'); if ~isempty(hAxes) set(gcf,'Pointer','fleur'); else set(gcf,'Pointer','arrow'); end
A CSSM reader has noted that since overobj uses the findobj function, it is rather slow. Therefore, do not use overobj in a complex figure’s WindowButtonMotionFcn callback.
overobj has other annoying limitations: it only searches direct figure children, not inner descendants. Therefore, anything contained within a uipanel, uibuttongroup etc. cannot be found. Also, it assumes the root and figure units are both ‘pixel’: often they are not. Also, it only searches visible objects: hidden axes are not retrieved. Finally, it would be a great benefit to have an overobj variant in which the Type argument is optional, so the function would return the handle of the first object found, of whichever type. Here’s this variant overobj2, adapted from Matlab’s overobj. Note that overobj and overobj2 only work on objects having a Position property, and so cannot be used for axes plot children:
function h = overobj2(varargin) %OVEROBJ2 Get handle of object that the pointer is over. % H = OVEROBJ2 searches all objects in the PointerWindow % looking for one that is under the pointer. Returns first % object handle it finds under the pointer, or empty matrix. % % H = OVEROBJ2(FINDOBJ_PROPS) searches all objects which are % descendants of the figure beneath the pointer and that are % returned by FINDOBJ with the specified arguments. % % Example: % h = overobj2('type','axes'); % h = overobj2('flat','visible','on'); % % See also OVEROBJ, FINDOBJ % Ensure root units are pixels oldUnits = get(0,'units'); set(0,'units','pixels'); % Get the figure beneath the mouse pointer & mouse pointer pos fig = get(0,'PointerWindow'); p = get(0,'PointerLocation'); set(0,'units',oldUnits); % Look for quick exit (if mouse pointer is not over any figure) if fig==0, h=[]; return; end % Compute figure offset of mouse pointer in pixels figPos = getpixelposition(fig); x = (p(1)-figPos(1)); y = (p(2)-figPos(2)); % Loop over all figure descendents c = findobj(get(fig,'Children'),varargin{:}); for h = c', % If descendent contains the mouse pointer position, exit r = getpixelposition(h); if (x>r(1)) && (x<r(1)+r(3)) && (y>r(2)) && (y<r(2)+r(4)) return end end h = [];
An alternative to overobj or overobj2 is to use the undocumented hittest built-in function – separate cases may dictate preferring one alternative to the other:
hObj = hittest(hFig);
p.s. – while most of Matlab’s undocumented stuff indeed lies in the Java domain, there are quite a few non-Java pearls to be exposed, as in this article. From time to time I will take time off from Java and describe these aspects.




