File: ConfirmInfo.m

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (276 lines) | stat: -rw-r--r-- 11,032 bytes parent folder | download | duplicates (3)
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
function ReturnFigh = ConfirmInfo(TheQuestion,ButtonString,HowLongToWait)
% Syntax: [FigureHandle] = ConfirmInfo(TheQuestion,[ButtonString],[TimeoutPeriod])
% 
% Purpose: Create simple dialog box asking user to verify receipt of information.
%
% On Octave, or Matlab in non-GUI mode, 
% this will just print 'TheQuestion' to the command window and wait for a key
% press for confirmation. Older Matlab versions present a GUI dialog box.
%
% 'TheQuestion' Text string with the question/statement to confirm.
% 'ButtonString' Optional label on the GUI button, otherwise 'Okay' is used.
% 'HowLongToWait' How long to wait for response before timing out. Defaults to
%                 infinite wait.
%
% History: 1/11/05    mpr   modified this from TwoStateQuery
%          1/21/05    mpr   allowed font size to be reduced for longer strings
%           5/3/06    mpr   added third argument to limit time for response;
%                           defaults to Inf; works only in version 7 (requires
%                           timer object class)
%          5/15/06    mpr   allowed figure to be non-modal; under that
%                           condition, clicking button deletes figure; to make
%                           nonmodal, in version 5, pass non-zero non-Inf third
%                           argument; in version 7, pass NaN as third argument;
%                           also added return argument to allow calling function
%                           to delete figure if user fails to delete figure and
%                           program proceeds 
%          8/26/06    mpr   repainted buttons in version 7
%         12/14/07    mpr   commented call to RepaintAllPushButtons because
%                           the Matlab bug is now almost fixed 
%         12/29/07    mpr   made three-line questions possible
%          1/3/08     mpr   introduced NLChar for cross-platform compatibility
%          3/5/08     mpr   small cosmetic fix for new case where a third line
%                           was needed even though Extent(3) < 2...
%          3/21/08    mpr   allowed return value to signal if user closed window
%                           instead of clicking uicontrol button (works only if
%                           figure is modal)
%          3/31/08    mpr   added check to make sure search for appropriate
%                           space does not overrun number of spaces
%          5/20/13    mk    Add text only fallback for Octave and non-GUI.
%          7/20/17    mk    Use text only fallback on Matlab R2014b and later.
%          7/11/19    mk    GUI version now works on Matlab R2014b and later.
DoModal = 1;
if nargin < 3 || isempty(HowLongToWait)
  HowLongToWait = Inf;
end

% Provide text fallback for non-GUI mode or Octave:
if ~IsGUI || IsOctave
  fprintf('%s\nPress any key to continue.\n', TheQuestion);
  [secs, keyCode] = KbStrokeWait (-1, GetSecs + HowLongToWait);
  if any(keyCode)
    ReturnFigh = 1;
  else
    ReturnFigh = 0;
  end
  return;
end

ThisVersion = version;
if str2num(ThisVersion(1)) < 7
	if ~isinf(HowLongToWait)
		DoModal = 0;
	end
  HowLongToWait = Inf;
elseif isnan(HowLongToWait)
	DoModal = 0;
	HowLongToWait = Inf;
end

if nargin < 2 || isempty(ButtonString)
	ButtonString = 'Okay';
end	

NLChar = abs(sprintf('\n'));

FigPos = [300 600];
FigWidth = 500;
FigHeight = 200;
OkayBPos = [210 25];
OkayBWidth = 80;
OkayBHeight = 50;

PrimeFontSize = 36;

QueryFigh = figure('Position',[FigPos FigWidth FigHeight],'Resize','off','NumberTitle','off', ...
    'Name','Acknowledge','Menubar','none','Color','k');
QueryFighNr = QueryFigh;
if ~isnumeric(QueryFighNr)
    QueryFighNr = QueryFigh.Number;
end
set(QueryFigh,'Tag',['Confirmation Figure ' int2str(QueryFighNr)]);
axes('Position',[0 0 1 1],'XLim',[0 FigWidth],'YLim',[0 FigHeight],'XColor','k','YColor','k');
th=text(FigWidth/2,0.7*FigHeight,TheQuestion,'FontSize',PrimeFontSize,'Color',get_color('hot pink'), ...
				'HorizontalAlignment','Center');
set(th,'Units','normalized');
TextExt = get(th,'Extent');

% There must be better ways to do what I do in this next condition...  At
% first this function was used only with short questions... questions that
% fit on one line.  When I started using it with longer questions, I
% started reducing the font size.  Then I decided I wanted to wrap lines so
% that I could put longer questions with larger font sizes.  Then I found
% there were times I wanted to wrap again because two lines required a font
% size too small...  The basic idea is to add carriage returns and shrink
% fonts to get the text to fit in a box of size pre-defined by the figure
% size.  It would probably be better at times to manipulate the size of the
% box as well as font sizes and number of lines.  But I'm not trying to
% accommodate all strings... I don't want to create a word processor!  I
% just want to get the aesthetics acceptable for questions of lengths within
% a reasonably restricted range.  What follows is ugly and inelegant, but
% it suits my needs.  Good enough to pass a cursory inspection anyways.
% Although in some versions of Matlab, the visibility box doesn't extend all the
% way out to the edges and bits of text at the margins are clipped.  Doesn't
% seem to be anything I can do about that except add blank spaces, but I don't
% know where the margins will be a priori and the problem doesn't bother me
% enough to make me want to write a fix...
% -- mpr

if TextExt(1) < 0
	SpaceLocs = find(TheQuestion == 32);
  
  if TextExt(3) > 3
    while TextExt(3) > 3 && get(th,'FontSize') > 8
      set(th,'FontSize',get(th,'FontSize')-1);
      TextExt = get(th,'Extent');
    end
    set(th,'String',TheQuestion(1:(SpaceLocs(1)-1)));
    SpaceNum = 1;
    PTextExt = get(th,'Extent');
    while PTextExt(3) < 0.95
      SpaceNum = SpaceNum+1;
      set(th,'String',TheQuestion(1:(SpaceLocs(SpaceNum)-1)));
      PTextExt = get(th,'Extent');
    end
    SpaceNum = SpaceNum-1;
    TheQuestion(SpaceLocs(SpaceNum)) = NLChar;
    SpaceEnd = SpaceNum;
    set(th,'String',TheQuestion((SpaceLocs(SpaceNum)+1):(SpaceLocs(SpaceEnd)-1)));
    PTextExt = get(th,'Extent');
    while PTextExt(3) < 0.95
      SpaceEnd = SpaceEnd+1;
      set(th,'String',TheQuestion((SpaceLocs(SpaceNum)+1):(SpaceLocs(SpaceEnd)-1)));
      PTextExt = get(th,'Extent');
    end
    TheQuestion(SpaceLocs(SpaceEnd-1)) = NLChar;
    set(th,'String',TheQuestion);
    TextExt = get(th,'Extent');
    while TextExt(3) > 0.95 && get(th,'FontSize') > 8
      set(th,'FontSize',get(th,'FontSize')-1);
      TextExt = get(th,'Extent');
    end
    if TextExt(3) > 1
      error('Question too large!');
    end
  elseif TextExt(3) > 2
    while TextExt(3) > 2 && get(th,'FontSize') > 8
      set(th,'FontSize',get(th,'FontSize')-1)
      TextExt = get(th,'Extent');
    end
    SpaceEnd = 1;
    set(th,'String',TheQuestion(1:(SpaceLocs(1)-1)));
    TextExt = get(th,'Extent');
    while TextExt(3) < 0.95
      SpaceEnd = SpaceEnd+1;
      if SpaceEnd > length(SpaceLocs)
        SpaceEnd = SpaceEnd-1;
        break;
      end
      set(th,'String',TheQuestion(1:(SpaceLocs(SpaceEnd)-1)));
      TextExt = get(th,'Extent');
    end
    TheQuestion(SpaceLocs(SpaceEnd-1)) = NLChar;
    set(th,'String',TheQuestion);
    TextExt = get(th,'Extent');
    while TextExt(3) > 0.95 && get(th,'FontSize') > 8
      set(th,'FontSize',get(th,'FontSize')-1);
      TextExt = get(th,'Extent');
    end
  elseif TextExt(3) > 0.95
    SpaceEnd = 1;
    set(th,'String',TheQuestion(1:(SpaceLocs(1)-1)));
    TextExt = get(th,'Extent');
    while TextExt(3) < 0.95
      SpaceEnd = SpaceEnd+1;
      if SpaceEnd > length(SpaceLocs)
        SpaceEnd = SpaceEnd-1;
        break;
      end
      set(th,'String',TheQuestion(1:(SpaceLocs(SpaceEnd)-1)));
      TextExt = get(th,'Extent');
    end
    TheQuestion(SpaceLocs(SpaceEnd-1)) = NLChar;
    set(th,'String',TheQuestion);
		TextExt = get(th,'Extent');
		if TextExt(3) > 0.95
			TheQuestion(SpaceLocs(end)) = NLChar;
			set(th,'String',TheQuestion);
			TextExt = get(th,'Extent');
			EndSpace = length(SpaceLocs);
			while TextExt(3) > 0.95 && EndSpace > SpaceEnd
				TheQuestion(SpaceLocs(EndSpace)) = ' ';
				EndSpace = EndSpace-1;
				TheQuestion(SpaceLocs(EndSpace)) = NLChar;
				set(th,'String',TheQuestion);
				TextExt = get(th,'Extent');
			end
		end
  end
end
OkayBh = uicontrol('Style','PushButton','Position',[OkayBPos OkayBWidth OkayBHeight],'String',ButtonString, ...
									'ForeGroundColor',get_color('midnight blue'),'BackgroundColor', ...
									get_color('wheat'),'FontSize',36,'Tag','OkayButton','UserData',-1);
set(OkayBh,'CallBack',['set(findobj(' int2str(QueryFighNr) ',''Tag'',''OkayButton''),''UserData'',1);']);
OkayBSSize = get(OkayBh,'Extent');
while OkayBSSize(3) > OkayBWidth
	if OkayBPos(1)+OkayBWidth > FigWidth - OkayBWidth/2
		set(uih,'FontSize',get(uih,'FontSize')-12);
		if ~get(uih,'FontSize')
			error('Okay string is too big!');
		end
	else
		OkayBPos(1) = OkayBPos(1) - (OkayBSSize(3)-OkayBWidth)/2;
		OkayBWidth = 1.1*OkayBSSize(3);
		set(OkayBh,'Position',[OkayBPos OkayBWidth OkayBHeight]);
	end
	OkayBSSize = get(OkayBh,'Extent');
end

drawnow;
if ~isinf(HowLongToWait)
  QFh = QueryFigh; % Just to shorten callback lines...
  TimerHandle = timer('TimerFcn',['if ishandle(' int2str(QFh) '), ' ...
                                  '  if strcmp(get(' int2str(QFh) ',''Tag''),''Confirmation Figure ' int2str(QFh) '''), ' ...
                                  '    set(findobj(' int2str(QFh) ',''Tag'',''OkayButton''),''UserData'',1); ' ...
                                  '  end; ' ...
                                  'end; ' ...
                                  'stop(timerfind(''Tag'',''Timer for ' int2str(QFh) ''')); ' ...
                                  'delete(timerfind(''Tag'',''Timer for ' int2str(QFh) '''));'], ...
                      'StartDelay',HowLongToWait,'Tag',['Timer for ' int2str(QFh)],'Period',HowLongToWait);
  start(TimerHandle);
end
if DoModal
	waitfor(OkayBh,'UserData');
	
	if ~isinf(HowLongToWait)
	  TimerHandle = timerfind('Tag',['Timer for ' int2str(QFh)]);
	  if ~isempty(TimerHandle)
	    stop(TimerHandle);
	    delete(TimerHandle);
	  end
  end
	
  UserHitOkay = ishandle(OkayBh);
  
	delete(findobj('Tag',['Confirmation Figure ' int2str(QueryFighNr)]));
else
  UserHitOkay = 1;
	set(OkayBh,'CallBack',['delete(' int2str(QueryFighNr) ');']);
end

if nargout
  % Variable name only makes sense for modal figure; which is ironic because if
  % user hits okay, then QueryFigh is no longer a valid handle.  This logic will
  % work for me, though.  Even with a bit of illogic...  as long as the
  % functions calling this know what the return value really signifies which
  % should always be clear because a zero return makes no sense for a non-modal
  % window, and a non-zero value makes no sense for a modal window.  Aside from
  % signifying how the window was closed, that is...
  if UserHitOkay
    ReturnFigh = QueryFigh;
  else
    ReturnFigh = 0;
  end
end

return;