-
Notifications
You must be signed in to change notification settings - Fork 0
/
zinput.m
208 lines (186 loc) · 6.01 KB
/
zinput.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
function [out_regs] = zinput(arg1)
% ZINPUT - Graphical input from mouse with zoom
%
% [OUT_REGS] = ZINPUT(N) gets N points or regions from the
% current axes and returns the X- and Y-ranges in a length Nx4
% matrix OUT_REGS.
% The cursor can be positioned using a mouse. Data points are entered by
% pressing the right mouse button, the region of the current axis
% are selected with the middle button, left button is for
% zooming, single cklick zooms in, click-and drag zooms to
% region (and doubble-click should zoom out - feature pending).
% Any key on the keyboard except carriage return zooms out to the
% orignal axis except carriage return, which terminates the input
% before N points are entered.
%
% [OUT_REGS] = ZINPUT gathers an unlimited number of points until the
% return key is pressed.
%
% See also GINPUT
% Copyright Bjorn Gustavsson 20050314
ax0 = axis;
out_regs = [];
c = computer;
if ~strcmp(c(1:2),'PC')
tp = get(0,'TerminalProtocol');
else
tp = 'micro';
end
if ~strcmp(tp,'none') & ~strcmp(tp,'x') & ~strcmp(tp,'micro') & 0,
% I dont know about this so better make short-cut and blindly try
% what works for X in all environments - sorry about that.
else
fig = gcf;
figure(gcf);
if nargin == 0
how_many = inf;
b = [];
else
how_many = arg1;
b = [];
if isstr(how_many) ...
| size(how_many,1) ~= 1 | size(how_many,2) ~= 1 ...
| ~(fix(how_many) == how_many) ...
| how_many < 0
error('Requires a positive integer.');
end
if how_many == 0
ptr_fig = 0;
while(ptr_fig ~= fig)
ptr_fig = get(0,'PointerWindow');
end
scrn_pt = get(0,'PointerLocation');
loc = get(fig,'Position');
pt = [scrn_pt(1) - loc(1), scrn_pt(2) - loc(2)];
out1 = pt(1); y = pt(2);
elseif how_many < 0
error('Argument must be a positive integer.');
end
end
% Remove figure button functions
state = uisuspend(fig);
pointer = get(gcf,'pointer');
set(gcf,'pointer','fullcrosshair');
fig_units = get(fig,'units');
char = 0;
while size(out_regs,1) < how_many
% Use no-side effect WAITFORBUTTONPRESS
waserr = 0;
try
keydown = wfbp;
catch
waserr = 1;
end
if(waserr == 1)
if(ishandle(fig))
set(fig,'units',fig_units);
uirestore(state);
error('Interrupted');
else
error('Interrupted by figure deletion');
end
end
ptr_fig = get(0,'CurrentFigure');
if(ptr_fig == fig)
if keydown
axis(ax0);
char = get(fig, 'CurrentCharacter');
else
char = get(fig, 'CurrentCharacter');
button = abs(get(fig, 'CurrentCharacter'));
pnt = get(gcf,'currentpoint');
xy1 = get(gca,'currentpoint');
rbbox([pnt 0 0],pnt)
xy2 = get(gca,'currentpoint');
selection_type = get(gcf,'selectiontype');
if all(xy1==xy2)
ax1 = axis;
dx = abs(ax1(2)-ax1(1));
dy = abs(ax1(4)-ax1(3));
xmin = max(ax1(1),xy1(1)-dx/4);
xmax = min(ax1(2),xy1(1)+dx/4);
ymin = max(ax1(3),xy1(1,2)-dy/4);
ymax = min(ax1(4),xy1(1,2)+dy/4);
zoom2ax = [xmin xmax ymin ymax];
else
%%% zoom to selected rectangle
zoom2ax = [sort([xy1(1,1) xy2(1,1)]) sort([xy1(1,2) xy2(1,2)])];
end
switch selection_type
case 'normal'
axis(zoom2ax)
reg = [];
case 'alt'
reg = axis;
axis(ax0)
case 'extend'
reg = xy1(1,[1 1 2 2]);
axis(ax0)
otherwise %%% open (doubleclick in linux)
axis(ax0);
reg = [];
end
end
pt = get(gca, 'CurrentPoint');
if (char == 'r')
rmi = size(out_regs,1);
if rmi > 0
out_regs(rmi,:) = [];
end
set(fig, 'CurrentCharacter','q')
char = 'q';
reg = [];
end
if(char == 13) % & how_many ~= 0)
% if the return key was pressed, char will == 13,
% and that's our signal to break out of here whether
% or not we have collected all the requested data
% points.
% If this was an early breakout, don't include
% the <Return> key info in the return arrays.
% We will no longer count it if it's the last input.
break;
end
if ~isempty(reg)
out_regs = [out_regs;reg];
end
end
%[size(out_regs,1), how_many, size(out_regs,1) < how_many]
end
uirestore(state);
set(gcf,'pointer','arrow');
set(fig,'units',fig_units);
set(fig, 'CurrentCharacter','q');
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function key = wfbp
%WFBP Replacement for WAITFORBUTTONPRESS that has no side effects.
fig = gcf;
current_char = [];
% Now wait for that buttonpress, and check for error conditions
waserr = 0;
try
h=findall(fig,'type','uimenu','accel','C'); % Disabling ^C for edit menu so the only ^C is for
set(h,'accel',''); % interrupting the function.
keydown = waitforbuttonpress;
current_char = double(get(fig,'CurrentCharacter')); % Capturing the character.
if~isempty(current_char) & (keydown == 1) % If the character was generated by the
if(current_char == 3) % current keypress AND is ^C, set 'waserr'to 1
waserr = 1; % so that it errors out.
end
end
set(h,'accel','C'); % Set back the accelerator for edit menu.
catch
waserr = 1;
end
drawnow;
if(waserr == 1)
set(h,'accel','C'); % Set back the accelerator if it errored out.
error('Interrupted');
end
selection_type = get(gcf,'selectiontype');
if strcmp(selection_type,'open')
axis(ax0)
end
if nargout>0, key = keydown; end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%