How can i restrict the cross cursor in ginput function into a specific UIAxes instead of it showing in the whole appdesigner figure?

2 views (last 30 days)
Hello, I have created an appdesigner figure where i had 2 button essentially where as the user presses the first button a graph gets shown in the UIAxes completely fine but now i want after the user presses the other button it enables the user to selct a point, I managed to get it working using ginput but the cross cursor is being displayed in the whole appdesigner figure instead of it being restricted to the UIAxes where the graph is displayed
That is how the code currently looks like
% Button pushed function: SelectButton
function SelectButtonPushed(app, event)
% Set up figure handle visibility
fhv = app.UIFigure.HandleVisibility; % Current status
app.UIFigure.HandleVisibility = 'callback'; % Temporarily change visibility
% Set the current figure to the app's figure
set(0, 'CurrentFigure', app.UIFigure)
% Allow user to select a point on the graph in UIAxes3
[x_selected, ~] = ginput(1);
% Restore original figure handle visibility
app.UIFigure.HandleVisibility = fhv;
% Convert x-coordinate of selected point from milliseconds to seconds
selected_time = x_selected / 1000;
end

Accepted Answer

Voss
Voss on 12 Mar 2024
Edited: Voss on 12 Mar 2024
You can modify ginput to do that.
First make a copy of ginput.m, put it in your current folder and rename it to something like ginput_modified.m.
Then replace the function updateCrossHair in that file with this:
function updateCrossHair(fig, crossHair)
% update cross hair for figure.
gap = 3; % 3 pixel view port between the crosshairs
cp = hgconvertunits(fig, [fig.CurrentPoint 0 0], fig.Units, 'pixels', fig);
cp = cp(1:2);
ax = fig.CurrentAxes;
if isempty(ax)
return_early = true;
else
axPos = getpixelposition(ax,true);
axX = axPos(1);
axY = axPos(2);
axWidth = axPos(3);
axHeight = axPos(4);
return_early = cp(1) < axX+gap || cp(2) < axY+gap || cp(1)>axX+axWidth-gap || cp(2)>axY+axHeight-gap;
end
% Early return if point is outside the axes or no CurrentAxes
if return_early
set(fig,'Pointer','arrow');
set(crossHair, 'Visible', 'off');
return
end
cdata = NaN(16,16);
hotspot = [8,8];
set(gcf,'Pointer','custom','PointerShapeCData',cdata,'PointerShapeHotSpot',hotspot)
set(crossHair, 'Visible', 'on');
thickness = 1; % 1 Pixel thin lines.
set(crossHair(1), 'Position', [axX cp(2) cp(1)-axX-gap thickness]);
set(crossHair(2), 'Position', [cp(1)+gap cp(2) axX+axWidth-cp(1)-gap thickness]);
set(crossHair(3), 'Position', [cp(1) axY thickness cp(2)-axY-gap]);
set(crossHair(4), 'Position', [cp(1) cp(2)+gap thickness axY+axHeight-cp(2)-gap]);
end
Then call ginput_modified (or whatever you called it) from your code.
You need to make sure the uiaxes you want the crosshairs to show up in is the CurrentAxes of the uifigure, so do
app.UIFigure.CurrentAxes = app.UIAxes; % or whatever the relevant uiaxes is called in your app
before you call ginput_modified in your code.
  4 Comments

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 11 Mar 2024
  1 Comment
Dany Majed
Dany Majed on 11 Mar 2024
Can you please try giving me more clarification on that since i have been trying different methods and unfortunately none of them seem to solve my problem where i got to a stage where i started thinking could that be a limitation from Matlab or no it can be fixed therefore if that is the case I would like additional assistance on how to achieve that. Thanks in advance any help is highly appreciated.

Sign in to comment.

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!