Home > rest_20090422 > rest_spm5_files > nic_spm_input.m

nic_spm_input

PURPOSE ^

Comprehensive graphical and command line input function

SYNOPSIS ^

function varargout = nic_spm_input(varargin)

DESCRIPTION ^

 Comprehensive graphical and command line input function
 FORMATs (given in Programmers Help)
_______________________________________________________________________

 spm_input handles most forms of interactive user input for SPM.
 (File selection is handled by spm_get.m) This can be either via GUI
 with keyboard shortcuts (in the SPM "Interactive" window), or on the
 command line (in the MatLab command window) if requested.

 There are five types of input: String, Evaluated, Conditions, Buttons
 and Menus:  These prompt for string input; string input which is
 evaluated to give a numerical result; selection of one item from a
 set of buttons; selection of an item from a menu.

 - STRING, EVALUATED & CONDITION input -
 For STRING, EVALUATED and CONDITION input types, a prompt is
 displayed adjacent to an editable text entry widget (with a lilac
 background!). Clicking in the entry widget allows editing, pressing
 <RETURN> or <ENTER> enters the result. You must enter something,
 empty answers are not accepted. A default response may be pre-specified
 in the entry widget, which will then be outlined. Clicking the border
 accepts the default value.

 Basic editing of the entry widget is supported *without* clicking in
 the widget, provided no other graphics widget has the focus. (If a
 widget has the focus, it is shown highlighted with a thin coloured
 line. Clicking on the window background returns the focus to the
 window, enabling keyboard accelerators.). This enables you to type
 responses to a sequenic_e of questions without having to repeatedly
 click the mouse in the text widgets. Supported are BackSpace and
 Delete, line kill (^U). Other standard ASCII characters are appended
 to the text in the entry widget. Press <RETURN> or <ENTER> to submit
 your response.

 A ContextMenu is provided (in the figure background) giving access to
 relevant utilities inic_luding the facility to load input from a file
 (see spm_load.m and examples given below): Click the right button on
 the figure background.

 For EVALUATED input, the string submitted is evaluated in the base
 MatLab workspace (see MatLab's `eval` command) to give a numerical
 value. This permits the entry of numerics, matrices, expressions,
 functions or workspace variables. I.e.:
   i)  - a number, vector or matrix        e.g. "[1 2 3 4]"
                                                "[1:4]"
                                                "1:4"
  ii)  - an expression                     e.g. "pi^2"
                                                "exp(-[1:36]/5.321)"
 iii)  - a function (that will be invoked) e.g. "spm_load('tmp.dat')"
         (function must be on MATLABPATH)       "input_cov(36,5.321)"
  iv)  - a variable from the base workspace
                                           e.g. "tmp"

 The last three options provide a great deal of power: spm_load will
 load a matrix from an ASCII data file and return the results. When
 called without an argument, spm_load will pop up a file selection
 dialog. Alternatively, this facility can be gained from the
 ContextMenu. The second example assummes a custom funic_ion called
 input_cov has been written which expects two arguments, for example
 the following file saved as input_cov.m somewhere on the MATLABPATH
 (~/matlab, the matlab subdirectory of your home area, and the current
 directory, are on the MATLABPATH by default):

       function [x] = input_cov(n,decay)
       % data input routine - mono-exponential covariate
       % FORMAT [x] = input_cov(n,decay)
       % n     -  number of time points
       % decay - decay constant
       x = exp(-[1:n]/decay);

 Although this example is trivial, specifying large vectors of
 empirical data (e.g. reaction times for 72 scans) is efficient and
 reliable using this device. In the last option, a variable called tmp
 is picked up from the base workspace. To use this method, set the
 variables in the MatLab base workspace before starting an SPM
 procedure (but after starting the SPM interface). E.g.
 >> tmp=exp(-[1:36]/5.321)

 Occasionally a vector of a specific length will be required: This
 will be indicated in the prompt, which will start with "[#]", where
 # is the length of vector(s) required. (If a matrix is entered then
 at least one dimension should equal #.)

 Occasionally a specific type of number will be required. This should
 be obvious from the context. If you enter a number of the wrong type,
 you'll be alerted and asked to re-specify. The types are i) Real
 numbers; ii) Integers; iii) Whole numbers [0,1,2,3,...] & iv) Natural
 numbers [1,2,3,...]

 CONDITIONS type input is for getting indicator vectors. The features
 of evaluated input described above are complimented as follows:
   v)  - a compressed list of digits 0-9   e.g. "12121212"
  ii)  - a list of indicator characters    e.g. "abababab"
         a-z mapped to 1-26 in alphabetical order, *except* r ("rest")
         which is mapped to zero (case insensitive, [A:Z,a:z] only)
 ...in addition the response is checked to ensure integer condition indices.
 Occasionally a specific number of conditions will be required: This
 will be indicated in the prompt, which will end with (#), where # is
 the number of conditions required.

 CONTRAST type input is for getting contrast weight vectors. Enter
 contrasts as row-vectors. Contrast weight vectors will be padded with
 zeros to the correct length, and checked for validity. (Valid
 contrasts are estimable, which are those whose weights vector is in
 the row-space of the design matrix.)

 Errors in string evaluation for EVALUATED & CONDITION types are
 handled gracefully, the user notified, and prompted to re-enter.

 - BUTTON input -
 For Button input, the prompt is displayed adjacent to a small row of
 buttons. Press the approprate button. The default button (if
 available) has a dark outline. Keyboard accelerators are available
 (provided no graphics widget has the focus):  <RETURN> or <ENTER>
 selects the default button (if available). Typing the first character
 of the button label (case insensitive) "presses" that button. (If
 these Keys are not unique, then the integer keys 1,2,...  "press" the
 appropriate button.)

 The CommandLine variant presents a simple menu of buttons and prompts
 for a selection. Any default response is indicated, and accepted if
 an empty line is input.


 - MENU input -
 For Menu input, the prompt is displayed in a pull down menu widget.
 Using the mouse, a selection is made by pulling down the widget and
 releasing the mouse on the appropriate response. The default response
 (if set) is marked with an asterisk. Keyboard accelerators are
 available (provided no graphic widget has the focus) as follows: 'f',
 'n' or 'd' move forward to next response down; 'b', 'p' or 'u' move
 backwards to the previous response up the list; the number keys jump
 to the appropriate response number; <RETURN> or <ENTER> slelects the
 currently displayed response. If a default is available, then
 pressing <RETURN> or <ENTER> when the prompt is displayed jumps to
 the default response.

 The CommandLine variant presents a simple menu and prompts for a selection.
 Any default response is indicated, and accepted if an empty line is
 input.


 - Combination BUTTON/EDIT input -
 In this usage, you will be presented with a set of buttons and an
 editable text widget. Click one of the buttons to choose that option,
 or type your response in the edit widget. Any default response will
 be shown in the edit widget. The edit widget behaves in the same way
 as with the STRING/EVALUATED input, and expects a single number.
 Keypresses edit the text widget (rather than "press" the buttons)
 (provided no other graphics widget has the focus). A default response
 can be selected with the mouse by clicking the thick border of the
 edit widget.


 - Comand line -
 If YPos is 0 or global CMDLINE is true, then the command line is used.
 Negative YPos overrides CMDLINE, ensuring the GUI is used, at
 YPos=abs(YPos). Similarly relative YPos beginning with '!'
 (E.g.YPos='!+1') ensures the GUI is used.

 spm_input uses the SPM 'Interactive' window, which is 'Tag'ged
 'Interactive'. If there is no such window, then the current figure is
 used, or an 'Interactive' window created if no windows are open.

-----------------------------------------------------------------------
 Programers help is contained in the main body of spm_input.m
-----------------------------------------------------------------------
 See      : input.m     (MatLab Referenic_e Guide)
 See also : spm_get.m   (SPM file selector dialog)
          : spm_input.m (Input wrapper function - handles batch mode)
_______________________________________________________________________
 @(#)spm_input.m    2.8 Andrew Holmes 03/03/04

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

DOWNLOAD ^

nic_spm_input.m

SOURCE CODE ^

0001 function varargout = nic_spm_input(varargin)
0002 % Comprehensive graphical and command line input function
0003 % FORMATs (given in Programmers Help)
0004 %_______________________________________________________________________
0005 %
0006 % spm_input handles most forms of interactive user input for SPM.
0007 % (File selection is handled by spm_get.m) This can be either via GUI
0008 % with keyboard shortcuts (in the SPM "Interactive" window), or on the
0009 % command line (in the MatLab command window) if requested.
0010 %
0011 % There are five types of input: String, Evaluated, Conditions, Buttons
0012 % and Menus:  These prompt for string input; string input which is
0013 % evaluated to give a numerical result; selection of one item from a
0014 % set of buttons; selection of an item from a menu.
0015 %
0016 % - STRING, EVALUATED & CONDITION input -
0017 % For STRING, EVALUATED and CONDITION input types, a prompt is
0018 % displayed adjacent to an editable text entry widget (with a lilac
0019 % background!). Clicking in the entry widget allows editing, pressing
0020 % <RETURN> or <ENTER> enters the result. You must enter something,
0021 % empty answers are not accepted. A default response may be pre-specified
0022 % in the entry widget, which will then be outlined. Clicking the border
0023 % accepts the default value.
0024 %
0025 % Basic editing of the entry widget is supported *without* clicking in
0026 % the widget, provided no other graphics widget has the focus. (If a
0027 % widget has the focus, it is shown highlighted with a thin coloured
0028 % line. Clicking on the window background returns the focus to the
0029 % window, enabling keyboard accelerators.). This enables you to type
0030 % responses to a sequenic_e of questions without having to repeatedly
0031 % click the mouse in the text widgets. Supported are BackSpace and
0032 % Delete, line kill (^U). Other standard ASCII characters are appended
0033 % to the text in the entry widget. Press <RETURN> or <ENTER> to submit
0034 % your response.
0035 %
0036 % A ContextMenu is provided (in the figure background) giving access to
0037 % relevant utilities inic_luding the facility to load input from a file
0038 % (see spm_load.m and examples given below): Click the right button on
0039 % the figure background.
0040 %
0041 % For EVALUATED input, the string submitted is evaluated in the base
0042 % MatLab workspace (see MatLab's `eval` command) to give a numerical
0043 % value. This permits the entry of numerics, matrices, expressions,
0044 % functions or workspace variables. I.e.:
0045 %   i)  - a number, vector or matrix        e.g. "[1 2 3 4]"
0046 %                                                "[1:4]"
0047 %                                                "1:4"
0048 %  ii)  - an expression                     e.g. "pi^2"
0049 %                                                "exp(-[1:36]/5.321)"
0050 % iii)  - a function (that will be invoked) e.g. "spm_load('tmp.dat')"
0051 %         (function must be on MATLABPATH)       "input_cov(36,5.321)"
0052 %  iv)  - a variable from the base workspace
0053 %                                           e.g. "tmp"
0054 %
0055 % The last three options provide a great deal of power: spm_load will
0056 % load a matrix from an ASCII data file and return the results. When
0057 % called without an argument, spm_load will pop up a file selection
0058 % dialog. Alternatively, this facility can be gained from the
0059 % ContextMenu. The second example assummes a custom funic_ion called
0060 % input_cov has been written which expects two arguments, for example
0061 % the following file saved as input_cov.m somewhere on the MATLABPATH
0062 % (~/matlab, the matlab subdirectory of your home area, and the current
0063 % directory, are on the MATLABPATH by default):
0064 %
0065 %       function [x] = input_cov(n,decay)
0066 %       % data input routine - mono-exponential covariate
0067 %       % FORMAT [x] = input_cov(n,decay)
0068 %       % n     -  number of time points
0069 %       % decay - decay constant
0070 %       x = exp(-[1:n]/decay);
0071 %
0072 % Although this example is trivial, specifying large vectors of
0073 % empirical data (e.g. reaction times for 72 scans) is efficient and
0074 % reliable using this device. In the last option, a variable called tmp
0075 % is picked up from the base workspace. To use this method, set the
0076 % variables in the MatLab base workspace before starting an SPM
0077 % procedure (but after starting the SPM interface). E.g.
0078 % >> tmp=exp(-[1:36]/5.321)
0079 %
0080 % Occasionally a vector of a specific length will be required: This
0081 % will be indicated in the prompt, which will start with "[#]", where
0082 % # is the length of vector(s) required. (If a matrix is entered then
0083 % at least one dimension should equal #.)
0084 %
0085 % Occasionally a specific type of number will be required. This should
0086 % be obvious from the context. If you enter a number of the wrong type,
0087 % you'll be alerted and asked to re-specify. The types are i) Real
0088 % numbers; ii) Integers; iii) Whole numbers [0,1,2,3,...] & iv) Natural
0089 % numbers [1,2,3,...]
0090 %
0091 % CONDITIONS type input is for getting indicator vectors. The features
0092 % of evaluated input described above are complimented as follows:
0093 %   v)  - a compressed list of digits 0-9   e.g. "12121212"
0094 %  ii)  - a list of indicator characters    e.g. "abababab"
0095 %         a-z mapped to 1-26 in alphabetical order, *except* r ("rest")
0096 %         which is mapped to zero (case insensitive, [A:Z,a:z] only)
0097 % ...in addition the response is checked to ensure integer condition indices.
0098 % Occasionally a specific number of conditions will be required: This
0099 % will be indicated in the prompt, which will end with (#), where # is
0100 % the number of conditions required.
0101 %
0102 % CONTRAST type input is for getting contrast weight vectors. Enter
0103 % contrasts as row-vectors. Contrast weight vectors will be padded with
0104 % zeros to the correct length, and checked for validity. (Valid
0105 % contrasts are estimable, which are those whose weights vector is in
0106 % the row-space of the design matrix.)
0107 %
0108 % Errors in string evaluation for EVALUATED & CONDITION types are
0109 % handled gracefully, the user notified, and prompted to re-enter.
0110 %
0111 % - BUTTON input -
0112 % For Button input, the prompt is displayed adjacent to a small row of
0113 % buttons. Press the approprate button. The default button (if
0114 % available) has a dark outline. Keyboard accelerators are available
0115 % (provided no graphics widget has the focus):  <RETURN> or <ENTER>
0116 % selects the default button (if available). Typing the first character
0117 % of the button label (case insensitive) "presses" that button. (If
0118 % these Keys are not unique, then the integer keys 1,2,...  "press" the
0119 % appropriate button.)
0120 %
0121 % The CommandLine variant presents a simple menu of buttons and prompts
0122 % for a selection. Any default response is indicated, and accepted if
0123 % an empty line is input.
0124 %
0125 %
0126 % - MENU input -
0127 % For Menu input, the prompt is displayed in a pull down menu widget.
0128 % Using the mouse, a selection is made by pulling down the widget and
0129 % releasing the mouse on the appropriate response. The default response
0130 % (if set) is marked with an asterisk. Keyboard accelerators are
0131 % available (provided no graphic widget has the focus) as follows: 'f',
0132 % 'n' or 'd' move forward to next response down; 'b', 'p' or 'u' move
0133 % backwards to the previous response up the list; the number keys jump
0134 % to the appropriate response number; <RETURN> or <ENTER> slelects the
0135 % currently displayed response. If a default is available, then
0136 % pressing <RETURN> or <ENTER> when the prompt is displayed jumps to
0137 % the default response.
0138 %
0139 % The CommandLine variant presents a simple menu and prompts for a selection.
0140 % Any default response is indicated, and accepted if an empty line is
0141 % input.
0142 %
0143 %
0144 % - Combination BUTTON/EDIT input -
0145 % In this usage, you will be presented with a set of buttons and an
0146 % editable text widget. Click one of the buttons to choose that option,
0147 % or type your response in the edit widget. Any default response will
0148 % be shown in the edit widget. The edit widget behaves in the same way
0149 % as with the STRING/EVALUATED input, and expects a single number.
0150 % Keypresses edit the text widget (rather than "press" the buttons)
0151 % (provided no other graphics widget has the focus). A default response
0152 % can be selected with the mouse by clicking the thick border of the
0153 % edit widget.
0154 %
0155 %
0156 % - Comand line -
0157 % If YPos is 0 or global CMDLINE is true, then the command line is used.
0158 % Negative YPos overrides CMDLINE, ensuring the GUI is used, at
0159 % YPos=abs(YPos). Similarly relative YPos beginning with '!'
0160 % (E.g.YPos='!+1') ensures the GUI is used.
0161 %
0162 % spm_input uses the SPM 'Interactive' window, which is 'Tag'ged
0163 % 'Interactive'. If there is no such window, then the current figure is
0164 % used, or an 'Interactive' window created if no windows are open.
0165 %
0166 %-----------------------------------------------------------------------
0167 % Programers help is contained in the main body of spm_input.m
0168 %-----------------------------------------------------------------------
0169 % See      : input.m     (MatLab Referenic_e Guide)
0170 % See also : spm_get.m   (SPM file selector dialog)
0171 %          : spm_input.m (Input wrapper function - handles batch mode)
0172 %_______________________________________________________________________
0173 % @(#)spm_input.m    2.8 Andrew Holmes 03/03/04
0174 
0175 %=======================================================================
0176 % - FORMAT specifications for programers
0177 %=======================================================================
0178 % generic    - [p,YPos] = spm_input(Prompt,YPos,Type,...)
0179 % string     - [p,YPos] = spm_input(Prompt,YPos,'s',DefStr)
0180 % string+    - [p,YPos] = spm_input(Prompt,YPos,'s+',DefStr)
0181 % evaluated  - [p,YPos] = spm_input(Prompt,YPos,'e',DefStr,n)
0182 % - natural  - [p,YPos] = spm_input(Prompt,YPos,'n',DefStr,n,mx)
0183 % - whole    - [p,YPos] = spm_input(Prompt,YPos,'w',DefStr,n,mx)
0184 % - integer  - [p,YPos] = spm_input(Prompt,YPos,'i',DefStr,n)
0185 % - real     - [p,YPos] = spm_input(Prompt,YPos,'r',DefStr,n,mm)
0186 % condition  - [p,YPos] = spm_input(Prompt,YPos,'c',DefStr,n,m)
0187 % contrast   - [p,YPos] = spm_input(Prompt,YPos,'x',DefStr,n,X)
0188 % permutation- [p,YPos] = spm_input(Prompt,YPos,'p',DefStr,P,n)
0189 % button     - [p,YPos] = spm_input(Prompt,YPos,'b',Labels,Values,DefItem)
0190 % button/edit combo's (edit for string or typed scalar evaluated input)
0191 %              [p,YPos] = spm_input(Prompt,YPos,'b?1',Labels,Values,DefStr,mx)
0192 %   ...where ? in b?1 specifies edit widget type as with string & eval'd input
0193 %            - [p,YPos] = spm_input(Prompt,YPos,'n1',DefStr,mx)
0194 %            - [p,YPos] = spm_input(Prompt,YPos,'w1',DefStr,mx)
0195 % button dialog
0196 %            - [p,YPos] = spm_input(Prompt,YPos,'bd',...
0197 %                                Labels,Values,DefItem,Title)
0198 % menu       - [p,YPos] = spm_input(Prompt,YPos,'m',Labels,Values,DefItem)
0199 % display    -            spm_input(Message,YPos,'d',Label)
0200 % display    - (GUI only) spm_input(Alert,YPos,'d!',Label)
0201 %
0202 % yes/no     - [p,YPos] = spm_input(Prompt,YPos,'y/n',Values,DefItem)
0203 % buttons (shortcut) where Labels is a bar delimited string
0204 %            - [p,YPos] = spm_input(Prompt,YPos,Labels,Values,DefItem)
0205 %
0206 % NB: Natural numbers are [1:Inf), Whole numbers are [0:Inf)
0207 %
0208 % -- Parameters (input) --
0209 %
0210 % Prompt   - prompt string
0211 %          - Defaults (missing or empty) to 'Enter an expression'
0212 %
0213 % YPos     - (numeric) vertical position {1 - 12}
0214 %                  - overriden by global CMDLINE
0215 %                  - 0 for command line
0216 %                  - negative to force GUI
0217 %          - (string) relative vertical position E.g. '+1'
0218 %                  - relative to last position used
0219 %                  - overriden by global CMDLINE
0220 %                  - YPos(1)=='!' forces GUI E.g. '!+1'
0221 %                  - '_' is a shortcut for the lowest GUI position
0222 %          - Defaults (missing or empty) to '+1'
0223 %
0224 % Type     - type of interrogation
0225 %                  - 's'tring
0226 %                  - 's+' multi-line string
0227 %                     - p returned as cellstr (nx1 cell array of strings)
0228 %                     - DefStr can be a cellstr or string matrix
0229 %                  - 'e'valuated string
0230 %                     - 'n'atural numbers
0231 %                     - 'w'hole numbers
0232 %                     - 'i'ntegers
0233 %                     - 'r'eals
0234 %                  - 'c'ondition indicator vector
0235 %                  - 'x' - contrast entry
0236 %                     - If n(2) or design matrix X is specified, then
0237 %                       contrast matrices are padded with zeros to have
0238 %                       correct length.
0239 %                     - if design matrix X is specified, then contrasts are
0240 %                       checked for validity (i.e. in the row-space of X)
0241 %                       (checking handled by spm_SpUtil)
0242 %                  - 'b'uttons
0243 %                  - 'bd' - button dialog: Uses MatLab's questdlg
0244 %                     - For up to three buttons
0245 %                     - Prompt can be a cellstr with a long multiline message
0246 %                     - CmdLine support as with 'b' type
0247 %                  - button/edit combo's: 'be1','bn1','bw1','bi1','br1'
0248 %                     - second letter of b?1 specifies type for edit widget
0249 %                  - 'n1' - single natural number (buttons 1,2,... & edit)
0250 %                  - 'w1' - single whole number   (buttons 0,1,... & edit)
0251 %                  - 'm'enu pulldown
0252 %                  - 'y/n' : Yes or No buttons
0253 %                                    (See shortcuts below)
0254 %                  - bar delimited string : buttons with these labels
0255 %                                    (See shortcuts below)
0256 %          - Defaults (missing or empty) to 'e'
0257 %
0258 % DefStr   - Default string to be placed in entry widget for string and
0259 %            evaluated types
0260 %          - Defaults to ''
0261 %
0262 % n ('e', 'c' & 'p' types)
0263 %          - Size of matrix requred
0264 %          - NaN for 'e' type implies no checking - returns input as evaluated
0265 %          - length of n(:) specifies dimension - elements specify size
0266 %          - Inf implies no restriction
0267 %          - Scalar n expanded to [n,1] (i.e. a column vector)
0268 %            (except 'x' contrast type when it's [n,np] for np
0269 %          - E.g: [n,1] & [1,n] (scalar n) prompt for an n-vector,
0270 %                         returned as column or row vector respectively
0271 %                 [1,Inf] & [Inf,1] prompt for a single vector,
0272 %                         returned as column or row vector respectively
0273 %                 [n,Inf] & [Inf,n] prompts for any number of n-vectors,
0274 %                         returned with row/column dimension n respectively.
0275 %                 [a,b] prompts for an 2D matrix with row dimension a and
0276 %                         column dimension b
0277 %                 [a,Inf,b] prompt for a 3D matrix with row dimension a,
0278 %                         page dimension b, and any column dimension.
0279 %          - 'c' type can only deal with single vectors
0280 %          - NaN for 'c' type treated as Inf
0281 %          - Defaults (missing or empty) to NaN
0282 %
0283 % n ('x'type)
0284 %          - Number of contrasts required by 'x' type (n(1))
0285 %            ( n(2) can be used specify length of contrast vectors if )
0286 %            ( a design matrix isn't passed                           )
0287 %          - Defaults (missing or empty) to 1 - vector contrast
0288 %
0289 % mx ('n', 'w', 'n1', 'w1', 'bn1' & 'bw1' types)
0290 %          - Maximum value (inic_lusive)
0291 %
0292 % mm ('r' type)
0293 %          - Maximum and minimum values (inic_lusive)
0294 %
0295 % m        - Number of unique conditions required by 'c' type
0296 %          - Inf implies no restriction
0297 %          - Defaults (missing or empty) to Inf - no restriction
0298 %
0299 % P        - set (vector) of numbers of which a permutation is required
0300 %
0301 % X        - Design matrix for contrast checking in 'x' type
0302 %          - Can be either a straight matrix or a space structure (see spm_sp)
0303 %          - Column dimension of design matrix specifies length of contrast
0304 %            vectors (overriding n(2) is specified).
0305 %
0306 % Title    - Title for questdlg in 'bd' type
0307 %
0308 % Labels   - Labels for button and menu types.
0309 %                  - string matrix, one label per row
0310 %                  - bar delimited string
0311 %                            E.g. 'Anic_ova|Scaling|None'
0312 %
0313 % Values   - Return values corresponding to Labels for button and menu types
0314 %          - j-th row is returned if button / menu item j is selected
0315 %            (row vectors are transposed)
0316 %          - Defaults (missing or empty) to - (button) Labels
0317 %                                           - ( menu ) menu item numbers
0318 %
0319 % DefItem  - Default item number, for button and menu types.
0320 %
0321 % -- Parameters (output) --
0322 % p        - results
0323 % YPos     - Optional second output argument returns GUI position just used
0324 %
0325 %-----------------------------------------------------------------------
0326 % WINDOWS:
0327 %
0328 % spm_input uses the SPM 'Interactive' 'Tag'ged window. If this isn't
0329 % available and no figures are open, an 'Interactive' SPM window is
0330 % created (`spm('CreateIntWin')`). If figures are available, then the
0331 % current figure is used *unless* it is 'Tag'ged.
0332 %
0333 %-----------------------------------------------------------------------
0334 % SHORTCUTS:
0335 %
0336 % Buttons SHORTCUT - If the Type parameter is a bar delimited string, then
0337 % the Type is taken as 'b' with the specified labels, and the next parameter
0338 % (if specified) is taken for the Values.
0339 %
0340 % Yes/No question shortcut - p = spm_input(Prompt,YPos,'y/n') expands
0341 % to p = spm_input(Prompt,YPos,'b','yes|no',...), enabling easy use of
0342 % spm_input for yes/no dialogue. Values defaults to 'yn', so 'y' or 'n'
0343 % is returned as appropriate.
0344 %
0345 %-----------------------------------------------------------------------
0346 % EXAMPLES:
0347 %            ( Specified YPos is overriden if global CMDLINE is )
0348 %            ( true, when the command line versions are used.   )
0349 %
0350 %       p = spm_input
0351 %               Command line input of an evaluated string, default prompt.
0352 %       p = spm_input('Enter a value',1)
0353 %               Evaluated string input, prompted by 'Enter a value', in
0354 %               position 1 of the dialog figure.
0355 %       p = spm_input(str,'+1','e',0.001)
0356 %               Evaluated string input, prompted by contents of string str,
0357 %               in next position of the dialog figure.
0358 %               Default value of 0.001 offered.
0359 %       p = spm_input(str,2,'e',[],5)
0360 %               Evaluated string input, prompted by contents of string str,
0361 %               in second position of the dialog figure.
0362 %               Vector of length 5 required - returned as column vector
0363 %       p = spm_input(str,2,'e',[],[Inf,5])
0364 %               ...as above, but can enter multiple 5-vectors in a matrix,
0365 %               returned with 5-vectors in rows
0366 %       p = spm_input(str,0,'c','ababab')
0367 %               Condition string input, prompted by contents of string str
0368 %               Uses command line interface.
0369 %               Default string of 'ababab' offered.
0370 %       p = spm_input(str,0,'c','010101')
0371 %               As above, but default string of '010101' offered.
0372 %       [p,YPos] = spm_input(str,'0','s','Image')
0373 %               String input, same position as last used, prompted by str,
0374 %               default of 'Image' offered. YPos returns GUI position used.
0375 %       p = spm_input(str,'-1','y/n')
0376 %               Yes/No buttons for question with prompt str, in position one
0377 %               before the last used Returns 'y' or 'n'.
0378 %       p = spm_input(str,'-1','y/n',[1,0],2)
0379 %               As above, but returns 1 for yes response, 0 for no,
0380 %               with 'no' as the default response
0381 %       p = spm_input(str,4,'Anic_ova|Scaling')
0382 %               Presents two buttons labelled 'Anic_ova' & 'Scaling', with
0383 %               prompt str, in position 4 of the dialog figure. Returns the
0384 %               string on the depresed button, where buttons can be pressed
0385 %               with the mouse or by the respective keyboard accelerators
0386 %               'a' & 's' (or 'A' & 'S').
0387 %       p = spm_input(str,-4,'b','Anic_ova|Scaling',[],2)
0388 %               As above, but makes "Scaling" the default response, and
0389 %               overrides global CMDLINE
0390 %       p = spm_input(str,0,'b','Anic_ova|Scaling|None',[1,2,3])
0391 %               Prompts for [A]nic_ova / [S]caling / [N]one in MatLab command
0392 %               window, returns 1, 2, or 3 according to the first character
0393 %               of the entered string as one of 'a', 's', or 'n' (case
0394 %               insensitive).
0395 %       p = spm_input(str,1,'b','Anic_ova',1)
0396 %        Sinic_e there's only one button, this just displays the response
0397 %        in GUI position 1 (or on the command line if global CMDLINE
0398 %        is true), and returns 1.
0399 %    p = spm_input(str,'+0','br1','None|Mask',[-Inf,NaN],0.8)
0400 %               Presents two buttons labelled "None" & "Mask" (which return
0401 %               -Inf & NaN if clicked), together with an editable text widget
0402 %               for entry of a single real number. The default of 0.8 is
0403 %               initially presented in the edit window, and can be selected by
0404 %               pressing return.
0405 %        Uses the previous GUI position, unless global CMDLINE is true,
0406 %               in which case a command-line equivalent is used.
0407 %    p = spm_input(str,'+0','w1')
0408 %        Prompts for a single whole number using a combination of
0409 %        buttons and edit widget, using the previous GUI position,
0410 %        or the command line if global CMDLINE is true.
0411 %       p = spm_input(str,'!0','m','Single Subject|Multi Subject|Multi Study')
0412 %               Prints the prompt str in a pull down menu containing items
0413 %               'Single Subject', 'Multi Subject' & 'Multi Study'. When OK is
0414 %               clicked p is returned as the index of the  choice, 1,2, or 3
0415 %               respectively. Uses last used position in GUI, irrespective of
0416 %               global CMDLINE
0417 %       p = spm_input(str,5,'m',...
0418 %               'Single Subject|Multi Subject|Multi Study',...
0419 %               ['SS';'MS';'SP'],2)
0420 %               As above, but returns strings 'SS', 'MS', or 'SP' according to
0421 %               the respective choice, with 'MS; as the default response.
0422 %       p = spm_input(str,0,'m',...
0423 %               'Single Subject|Multi Subject|Multi Study',...
0424 %               ['SS';'MS';'SP'],2)
0425 %               As above, but the menu is presented in the command window
0426 %               as a numbered list.
0427 %       spm_input('Anic_ova, GrandMean scaling',0,'d')
0428 %               Displays message in a box in the MatLab command window
0429 %       [null,YPos]=spm_input('Session 1','+1','d!','fMRI')
0430 %        Displays 'fMRI: Session 1' in next GUI position of the
0431 %               'Interactive' window. If CMDLINE is 1, then nothing is done.
0432 %               Position used is returned in YPos.
0433 %
0434 %-----------------------------------------------------------------------
0435 % FORMAT h = spm_input(Prompt,YPos,'m!',Labels,cb,UD,XCB);
0436 % GUI PullDown menu utility - creates a pulldown menu in the Interactive window
0437 % FORMAT H = spm_input(Prompt,YPos,'b!',Labels,cb,UD,XCB);
0438 % GUI Buttons utility - creates GUI buttons in the Interactive window
0439 %
0440 % Prompt, YPos, Labels - as with 'm'enu/'b'utton types
0441 % cb  - CallBack string
0442 % UD  - UserData
0443 % XCB - Extended CallBack handling - allows different CallBack for each item,
0444 %       and use of UD in CallBack strings. [Defaults to 1 for PullDown type
0445 %       when multiple CallBacks specified, 0 o/w.]
0446 % H   - Handle of 'PullDown' uicontrol / 'Button's
0447 %
0448 % In "normal" mode (when XCB is false), this is essentially a utility
0449 % to create a PullDown menu widget or set of buttons in the SPM
0450 % 'Interactive' figure, using positioning and Label definition
0451 % convenienic_es of the spm_input 'm'enu & 'b'utton types. If Prompt is
0452 % not empty, then the PullDown/Buttons appears on the right, with the
0453 % Prompt on the left, otherwise the PullDown/Buttons use the whole
0454 % width of the Interactive figure. The PopUp's CallBack string is
0455 % specified in cb, and [optional] UserData may be passed as UD.
0456 %
0457 % For buttons, a separate callback can be specified for each button, by
0458 % passing the callbacks corresponding to the Labels as rows of a
0459 % cellstr or string matrix.
0460 %
0461 % This "different CallBacks" facility can also be extended to the
0462 % PullDown type, using the "extended callback" mode (when XCB is
0463 % true).  % In addition, in "extended callback", you can use UD to
0464 % refer to the UserData argument in the CallBack strings. (What happens
0465 % is this: The cb & UD are stored as fields in the PopUp's UserData
0466 % structure, and the PopUp's callback is set to spm_input('!m_cb'),
0467 % which reads UD into the functions workspace and eval's the
0468 % appropriate CallBack string.  Note that this means that base
0469 % workspace variables are inaccessible (put what you need in UD), and
0470 % that any return arguments from CallBack functions are not passed back
0471 % to the base workspace).
0472 %
0473 %
0474 %-----------------------------------------------------------------------
0475 % UTILITY functionS:
0476 %
0477 % FORMAT colour = spm_input('!Colour')
0478 % Returns colour for input widgets, as specified in COLOUR parameter at
0479 % start of code.
0480 % colour  - [r,g,b] colour triple
0481 %
0482 % FORMAT [iCond,msg] = spm_input('!iCond',str,n,m)
0483 % Parser for special 'c'ondition type: Handles digit strings and
0484 % strings of indicator chars.
0485 % str     - input string
0486 % n       - length of condition vector required    [defaut Inf - no restriction]
0487 % m       - number of conditions required    [default Inf - no restrictions]
0488 % iCond   - Integer condition indicator vector
0489 % msg     - status message
0490 %
0491 % FORMAT hM = spm_input('!InptConMen',Finter,H)
0492 % Sets a basic Input ContextMenu for the figure
0493 % Finter - figure to set menu in
0494 % H      - handles of objects to delete on "crash out" option
0495 % hM     - handle of UIContextMenu
0496 %
0497 % FORMAT [CmdLine,YPos] = spm_input('!CmdLine',YPos)
0498 % Sorts out whether to use CmdLine or not & canonicalises YPos
0499 % CmdLine - Binary flag
0500 % YPos    - Position index
0501 %
0502 % FORMAT Finter = spm_input('!GetWin',F)
0503 % Locates (or creates) figure to work in
0504 % F       - Interactive Figure, defaults to 'Interactive'
0505 % Finter  - Handle of figure to use
0506 %
0507 % FORMAT [PLoc,cF] = spm_input('!PointerJump',RRec,F,XDisp)
0508 % Raise window & jump pointer over question
0509 % RRec  - Response rectangle of current question
0510 % F     - Interactive Figure, Defaults to 'Interactive'
0511 % XDisp - X-displacement of cursor relative to RRec
0512 % PLoc  - Pointer location before jumping
0513 % cF    - Current figure before making F current.
0514 %
0515 % FORMAT [PLoc,cF] = spm_input('!PointerJumpBack',PLoc,cF)
0516 % Replace pointer and reset CurrentFigure back
0517 % PLoc  - Pointer location before jumping
0518 % cF    - Previous current figure
0519 %
0520 % FORMAT spm_input('!PrntPrmpt',Prompt,TipStr,Title)
0521 % Print prompt for CmdLine questioning
0522 % Prompt - prompt string, callstr, or string matrix
0523 % TipStr - tip string
0524 % Title  - title string
0525 %
0526 % FORMAT [Frec,QRec,PRec,RRec] = spm_input('!InputRects',YPos,rec,F)
0527 % Returns rectangles (pixels) used in GUI
0528 % YPos  - Position index
0529 % rec   - Rectangle specifier: String, one of 'Frec','QRec','PRec','RRec'
0530 %         Defaults to '', which returns them all.
0531 % F     - Interactive Figure, Defaults to spm_figure('FindWin','Interactive')
0532 % FRec  - Position of interactive window
0533 % QRec  - Position of entire question
0534 % PRec  - Position of prompt
0535 % RRec  - Position of response
0536 %
0537 % FORMAT spm_input('!DeleteInputObj',F)
0538 % Deltes input objects (only) from figure F
0539 % F     - Interactive Figure, Defaults to spm_figure('FindWin','Interactive')
0540 %
0541 % FORMAT [CPos,hCPos] = spm_input('!CurrentPos',F)
0542 % Returns currently used GUI question positions & their handles
0543 % F     - Interactive Figure, Defaults to spm_figure('FindWin','Interactive')
0544 % CPos  - Vector of position indices
0545 % hCPos - (n x CPos) matrix of object handles
0546 %
0547 % FORMAT h = spm_input('!FindInputObj',F)
0548 % Returns handles of input GUI objects in figure F
0549 % F - Interactive Figure, Defaults to spm_figure('FindWin','Interactive')
0550 % h - vector of object handles
0551 %
0552 % FORMAT [NPos,CPos,hCPos] = spm_input('!NextPos',YPos,F,CmdLine)
0553 % Returns next position index, specified by YPos
0554 % YPos    - Absolute (integer) or relative (string) position index
0555 %           Defaults to '+1'
0556 % F       - Interactive Figure, defaults to spm_figure('FindWin','Interactive')
0557 % CmdLine - Command line? Defaults to spm_input('!CmdLine',YPos)
0558 % NPos    - Next position index
0559 % CPos & hCPos - as for !CurrentPos
0560 %
0561 % FORMAT NPos = spm_input('!SetNextPos',YPos,F,CmdLine)
0562 % Sets up for input at next position index, specified by YPos. This utility
0563 % function can be used stand-alone to implicitly set the next position
0564 % by clearing positions NPos and greater.
0565 % YPos    - Absolute (integer) or relative (string) position index
0566 %           Defaults to '+1'
0567 % F       - Interactive Figure, defaults to spm_figure('FindWin','Interactive')
0568 % CmdLine - Command line? Defaults to spm_input('!CmdLine',YPos)
0569 % NPos    - Next position index
0570 %
0571 % FORMAT MPos = spm_input('!MaxPos',F,FRec3)
0572 % Returns maximum position index for figure F
0573 % F     - Interactive Figure, Defaults to spm_figure('FindWin','Interactive')
0574 %      Not required if FRec3 is specified
0575 % FRec3 - Length of interactive figure in pixels
0576 %
0577 % FORMAT spm_input('!EditableKeyPressFcn',h,ch)
0578 % KeyPress callback for GUI string / eval input
0579 %
0580 % FORMAT spm_input('!ButtonKeyPressFcn',h,Keys,DefItem,ch)
0581 % KeyPress callback for GUI buttons
0582 %
0583 % FORMAT spm_input('!PullDownKeyPressFcn',h,ch,DefItem)
0584 % KeyPress callback for GUI pulldown menus
0585 %
0586 % FORMAT spm_input('!m_cb')
0587 % Extended CallBack handler for 'p' PullDown utility type
0588 %
0589 % FORMAT spm_input('!dScroll',h,str)
0590 % Scroll text string in object h
0591 % h      - handle of text object
0592 % Prompt - Text to scroll (Defaults to 'UserData' of h)
0593 %
0594 %-----------------------------------------------------------------------
0595 % SUBfunctionS:
0596 %
0597 % FORMAT [Keys,Labs] = sf_labkeys(Labels)
0598 % Make unique character keys for the Labels, ignoring case.
0599 % Used with 'b'utton types.
0600 %
0601 % FORMAT [p,msg] = sf_eEval(str,Type,n,m)
0602 % Common code for evaluating various input types.
0603 %
0604 % FORMAT str = sf_SzStr(n,l)
0605 % Common code to construct prompt strings for pre-specified vector/matrix sizes
0606 %
0607 % FORMAT [p,msg] = sf_SzChk(p,n,msg)
0608 % Common code to check (& canonicalise) sizes of input vectors/matrices
0609 %
0610 %_______________________________________________________________________
0611 % @(#)spm_input.m    2.8 Andrew Holmes 03/03/04
0612 
0613 
0614 %-Parameters
0615 %=======================================================================
0616 COLOUR   = [.8,.8,1];    %-Question background colour
0617 PJump    = 1;        %-Jumping of pointer to question?
0618 TTips    = 1;        %-Use ToolTipStrings? (which can be annoying!)
0619 Conic_rash = 1;        %-Add "crash out" option to 'Interactive'fig.ContextMenu
0620 
0621 
0622 %-Condition arguments
0623 %=======================================================================
0624 if nargin<1|isempty(varargin{1}), Prompt=''; else, Prompt=varargin{1}; end
0625 
0626 if ~isempty(Prompt) & ischar(Prompt) & Prompt(1)=='!'
0627     %-Utility functions have Prompt string starting with '!'
0628     Type = Prompt;
0629 else            %-Should be an input request: get Type & YPos
0630     if nargin<3|isempty(varargin{3}), Type='e';  else, Type=varargin{3}; end
0631     if any(Type=='|'), Type='b|'; end
0632     if nargin<2|isempty(varargin{2}), YPos='+1'; else, YPos=varargin{2}; end
0633 
0634     [CmdLine,YPos] = nic_spm_input('!CmdLine',YPos);
0635 
0636     if ~CmdLine    %-Setup for GUI use
0637         %-Locate (or create) figure to work in
0638         Finter = nic_spm_input('!GetWin');
0639     
0640         %-Find out which Y-position to use, setup for use
0641         YPos = nic_spm_input('!SetNextPos',YPos,Finter,CmdLine);
0642     
0643         %-Determine position of objects
0644         [FRec,QRec,PRec,RRec]=nic_spm_input('!InputRects',YPos,'',Finter);
0645     end
0646 end
0647 
0648 
0649 switch lower(Type)
0650 case {'s','s+','e','n','w','i','r','c','x','p'}  %-String and evaluated input
0651 %=======================================================================
0652 %-Condition arguments
0653 if nargin<6|isempty(varargin{6}), m=[]; else, m=varargin{6}; end
0654 if nargin<5|isempty(varargin{5}), n=[]; else, n=varargin{5}; end
0655 if nargin<4, DefStr=''; else, DefStr=varargin{4}; end
0656 if strcmp(lower(Type),'s+')
0657     %-DefStr should be a cellstr for 's+' type.
0658     if isempty(DefStr), DefStr = {};
0659         else, DefStr = cellstr(DefStr); end
0660     DefStr = DefStr(:);
0661 else
0662     %-DefStr needs to be a string
0663     if ~ischar(DefStr), DefStr=num2str(DefStr); end
0664     DefStr = DefStr(:)';
0665 end
0666 
0667 strM='';
0668 switch lower(Type)            %-Type specific defaults/setup
0669 case 's', TTstr='enter string';
0670 case 's+',TTstr='enter string - multi-line';
0671 case 'e', TTstr='enter expression to evaluate';
0672 case 'n', TTstr='enter expression - natural number(s)';
0673     if ~isempty(m), strM=sprintf(' (in [1,%d])',m); TTstr=[TTstr,strM]; end
0674 case 'w', TTstr='enter expression - whole number(s)';
0675     if ~isempty(m), strM=sprintf(' (in [0,%d])',m); TTstr=[TTstr,strM]; end
0676 case 'i', TTstr='enter expression - integer(s)';
0677 case 'r', TTstr='enter expression - real number(s)';
0678     if ~isempty(m), TTstr=[TTstr,sprintf(' in [%g,%g]',min(m),max(m))]; end
0679 case 'c', TTstr='enter indicator vector e.g. 0101...  or abab...';
0680     if ~isempty(m) & isfinite(m), strM=sprintf(' (%d)',m); end
0681 case 'x', TTstr='enter contrast matrix';
0682 case 'p',
0683     if isempty(n), error('permutation of what?'), else, P=n(:)'; end
0684     if isempty(m), n = [1,length(P)]; end
0685     m = P;
0686     if ~length(setxor(m,[1:max(m)]))
0687         TTstr=['enter permutation of [1:',num2str(max(m)),']'];
0688     else
0689         TTstr=['enter permutation of [',num2str(m),']'];
0690     end
0691 otherwise, TTstr='enter expression'; end
0692 
0693 strN = sf_SzStr(n);
0694 
0695 
0696 if CmdLine                                   %-Use CmdLine to get answer
0697 %-----------------------------------------------------------------------
0698     nic_spm_input('!PrntPrmpt',[Prompt,strN,strM],TTstr)
0699 
0700     %-Do Eval Types in Base workspace, catch errors
0701     switch lower(Type), case 's'
0702         if ~isempty(DefStr)
0703             Prompt=[Prompt,' (Default: ',DefStr,' )'];
0704         end
0705         str = input([Prompt,' : '],'s');
0706         if isempty(str), str=DefStr; end
0707 
0708         while isempty(str)
0709             nic_spm('Beep')
0710             fprintf('! %s : enter something!\n',mfilename)
0711             str = input([Prompt,' : '],'s');
0712             if isempty(str), str=DefStr; end
0713         end
0714         p = str; msg = '';
0715 
0716     case 's+'
0717         fprintf(['Multi-line input: Type ''.'' on a line',...
0718             ' of its own to terminate input.\n'])
0719         if ~isempty(DefStr)
0720             fprintf('Default : (press return to accept)\n')
0721             fprintf('        : %s\n',DefStr{:})
0722         end
0723         fprintf('\n')
0724 
0725         str = input('l001 : ','s');
0726         while (isempty(str) | strcmp(str,'.')) & isempty(DefStr)
0727             nic_spm('Beep')
0728             fprintf('! %s : enter something!\n',mfilename)
0729             str = input('l001 : ','s');
0730         end
0731 
0732         if isempty(str)
0733             %-Accept default
0734             p = DefStr;
0735         else
0736             %-Got some input, allow entry of additional lines
0737             p = {str};
0738             str = input(sprintf('l%03u : ',length(p)+1),'s');
0739             while ~strcmp(str,'.')
0740                 p = [p;{str}];
0741                 str = input(sprintf('l%03u : ',length(p)+1),'s');
0742             end
0743         end
0744         msg = '';
0745 
0746     otherwise
0747         if ~isempty(DefStr)
0748             Prompt=[Prompt,' (Default: ',DefStr,' )'];
0749         end
0750         str = input([Prompt,' : '],'s');
0751         if isempty(str), str=DefStr; end
0752         [p,msg] = sf_eEval(str,Type,n,m);
0753 
0754         while isstr(p)
0755             nic_spm('Beep'), fprintf('! %s : %s\n',mfilename,msg)
0756             str = input([Prompt,' : '],'s');
0757             if isempty(str), str=DefStr; end
0758             [p,msg] = sf_eEval(str,Type,n,m);
0759         end
0760     end
0761     if ~isempty(msg), fprintf('\t%s\n',msg), end
0762 
0763 else                                             %-Use GUI to get answer
0764 %-----------------------------------------------------------------------
0765 
0766     %-Create text and edit control objects
0767     %---------------------------------------------------------------
0768     hPrmpt = uicontrol(Finter,'Style','Text',...
0769         'String',[strN,Prompt,strM],...
0770         'Tag',['GUIinput_',int2str(YPos)],...
0771         'UserData','',...
0772         'HorizontalAlignment','Right',...
0773         'Position',PRec);
0774 
0775 
0776 
0777     %-Default button surrounding edit widget (if a DefStr given)
0778     %-Callback sets hPrmpt UserData, and EditWidget string, to DefStr
0779     % (Buttons UserData holds handles [hPrmpt,hEditWidget], set later)
0780     cb = ['set(get(gcbo,''UserData'')*[1;0],''UserData'',',...
0781             'get(gcbo,''String'')),',...
0782         'set(get(gcbo,''UserData'')*[0;1],''String'',',...
0783             'get(gcbo,''String''))'];
0784     if ~isempty(DefStr)
0785         if iscellstr(DefStr), str=[DefStr{1},'...'];
0786             else, str=DefStr; end
0787         hDef = uicontrol(Finter,'Style','PushButton',...
0788             'String',DefStr,...
0789             'ToolTipString',...
0790                 ['Click on border to accept default: ' str],...
0791             'Tag',['GUIinput_',int2str(YPos)],...
0792             'UserData',[],...
0793             'CallBack',cb,...
0794             'Position',RRec+[-2,-2,+4,+4]);
0795     else
0796         hDef = [];
0797     end
0798 
0799     %-Edit widget: Callback puts string into hPrompts UserData
0800     cb = 'set(get(gcbo,''UserData''),''UserData'',get(gcbo,''String''))';
0801     h = uicontrol(Finter,'Style','Edit',...
0802         'String',DefStr,...
0803         'Max',strcmp(lower(Type),'s+')+1,...
0804         'Tag',['GUIinput_',int2str(YPos)],...
0805         'UserData',hPrmpt,...
0806         'CallBack',cb,...
0807         'Horizontalalignment','Left',...
0808         'BackgroundColor',COLOUR,...
0809         'Position',RRec);
0810     set(hDef,'UserData',[hPrmpt,h])
0811     if TTips, set(h,'ToolTipString',TTstr), end
0812 
0813     %-Figure ContextMenu for shortcuts
0814     hM = nic_spm_input('!InptConMen',Finter,[hPrmpt,hDef,h]);
0815     cb = [    'set(get(gcbo,''UserData''),''String'',',...
0816             '[''nic_spm_load('''''',nic_spm_get(1),'''''')'']), ',...
0817         'set(get(get(gcbo,''UserData''),''UserData''),''UserData'',',...
0818             'get(get(gcbo,''UserData''),''String''))'];
0819     uimenu(hM,'Label','load from text file','Separator','on',...
0820         'CallBack',cb,'UserData',h)
0821 
0822     %-Bring window to fore & jump pointer to edit widget
0823     [PLoc,cF] = nic_spm_input('!PointerJump',RRec,Finter);
0824 
0825     %-Setup FigureKeyPressFcn for editing of entry widget without clicking
0826     set(Finter,'KeyPressFcn',[...
0827         'nic_spm_input(''!EditableKeyPressFcn'',',...
0828         'findobj(gcf,''Tag'',''GUIinput_',int2str(YPos),''',',...
0829             '''Style'',''edit''),',...
0830         'get(gcbf,''CurrentCharacter''))'])
0831 
0832 
0833     %-Wait for edit, do eval Types in Base workspace, catch errors
0834     %---------------------------------------------------------------
0835     waitfor(hPrmpt,'UserData')
0836     if ~ishandle(hPrmpt), error(['Input window cleared whilst waiting ',...
0837         'for response: Bailing out!']), end
0838     str = get(hPrmpt,'UserData');
0839     switch lower(Type), case 's'
0840         p = str; msg = '';
0841     case 's+'
0842         p = cellstr(str); msg = '';
0843     otherwise
0844         [p,msg] = sf_eEval(str,Type,n,m);
0845         while isstr(p)
0846             set(h,'Style','Text',...
0847                 'String',msg,'HorizontalAlignment','Center',...
0848                 'ForegroundColor','r')
0849             nic_spm('Beep'), pause(2)
0850             set(h,'Style','Edit',...
0851                 'String',str,...
0852                 'HorizontalAlignment','Left',...
0853                 'ForegroundColor','k')
0854             %set(hPrmpt,'UserData','');
0855             waitfor(hPrmpt,'UserData')
0856             if ~ishandle(hPrmpt), error(['Input window cleared ',...
0857                 'whilst waiting for response: Bailing out!']),end
0858             str = get(hPrmpt,'UserData');
0859             [p,msg] = sf_eEval(str,Type,n,m);
0860         end
0861     end
0862 
0863     %-Fix edit window, clean up, reposition pointer, set CurrentFig back
0864     delete([hM,hDef]), set(Finter,'KeyPressFcn','')
0865     set(h,'Style','Text','HorizontalAlignment','Center',...
0866         'ToolTipString',msg,...
0867         'BackgroundColor',[.7,.7,.7])
0868     nic_spm_input('!PointerJumpBack',PLoc,cF)
0869     drawnow
0870 
0871 end % (if CmdLine)
0872 
0873 %-Log the transaction & return response
0874 %-----------------------------------------------------------------------
0875 if exist('nic_spm_log')==2
0876     switch lower(Type), case 's'
0877         nic_spm_log([mfilename,' : ',Prompt,':',p]);
0878     case 's+'
0879         nic_spm_log([mfilename,' : ',Prompt,':'],p);
0880     otherwise
0881         nic_spm_log([mfilename,' : ',Prompt,': (',str,')'],p);
0882     end
0883 end
0884 varargout = {p,YPos};
0885 
0886 
0887 case {'b','bd','b|','y/n','be1','bn1','bw1','bi1','br1',...
0888     '-n1','n1','-w1','w1','m'}             %-'b'utton & 'm'enu Types
0889 %=======================================================================
0890 %-Condition arguments
0891 switch lower(Type), case {'b','be1','bi1','br1','m'}
0892     m = []; Title = '';
0893     if nargin<6, DefItem=[];  else, DefItem=varargin{6}; end
0894     if nargin<5, Values=[];   else, Values =varargin{5}; end
0895     if nargin<4, Labels='';   else, Labels =varargin{4}; end
0896 case 'bd'
0897     if nargin<7, Title='';    else, Title  =varargin{7}; end
0898     if nargin<6, DefItem=[];  else, DefItem=varargin{6}; end
0899     if nargin<5, Values=[];   else, Values =varargin{5}; end
0900     if nargin<4, Labels='';   else, Labels =varargin{4}; end
0901 case 'y/n'
0902     Title = '';
0903     if nargin<5, DefItem=[];  else, DefItem=varargin{5}; end
0904     if nargin<4, Values=[];   else, Values =varargin{4}; end
0905     if isempty(Values), Values='yn'; end
0906     Labels = {'yes','no'};
0907 case 'b|'
0908     Title = '';
0909     if nargin<5, DefItem=[];  else, DefItem=varargin{5}; end
0910     if nargin<4, Values=[];   else, Values =varargin{4}; end
0911     Labels = varargin{3};
0912 case 'bn1'
0913     if nargin<7, m=[];        else, m=varargin{7};       end
0914     if nargin<6, DefItem=[];  else, DefItem=varargin{6}; end
0915     if nargin<5, Values=[];   else, Values =varargin{5}; end
0916     if nargin<4, Labels=[1:5]'; Values=[1:5]; Type='-n1';
0917         else, Labels=varargin{4}; end
0918 case 'bw1'
0919     if nargin<7, m=[];        else, m=varargin{7};       end
0920     if nargin<6, DefItem=[];  else, DefItem=varargin{6}; end
0921     if nargin<5, Values=[];   else, Values =varargin{5}; end
0922     if nargin<4, Labels=[0:4]'; Values=[0:4]; Type='-w1';
0923         else, Labels=varargin{4}; end
0924 case {'-n1','n1','-w1','w1'}
0925     if nargin<5, m=[];        else, m=varargin{5};       end
0926     if nargin<4, DefItem=[];  else, DefItem=varargin{4}; end
0927     switch lower(Type)
0928     case {'n1','-n1'}, Labels=[1:min([5,m])]'; Values=Labels'; Type='-n1';
0929     case {'w1','-w1'}, Labels=[0:min([4,m])]'; Values=Labels'; Type='-w1';
0930     end
0931 end
0932 
0933 
0934 %-Check some labels were specified
0935 if isempty(Labels), error('No Labels specified'), end
0936 
0937 if iscellstr(Labels), Labels=char(Labels); end
0938 
0939 %-Convert Labels "option" string to string matrix if required
0940 if ischar(Labels) & any(Labels=='|')
0941     OptStr=Labels;
0942     BarPos=find([OptStr=='|',1]);
0943     Labels=OptStr(1:BarPos(1)-1);
0944     for Bar = 2:sum(OptStr=='|')+1
0945         Labels=strvcat(Labels,OptStr(BarPos(Bar-1)+1:BarPos(Bar)-1));
0946     end
0947 end
0948 
0949 
0950 %-Set default Values for the Labels
0951 if isempty(Values)
0952     if strcmp(lower(Type),'m')
0953         Values=[1:size(Labels,1)]';
0954     else
0955         Values=Labels;
0956     end
0957 else
0958     %-Make sure Values are in rows
0959     if size(Labels,1)>1 & size(Values,1)==1, Values = Values'; end
0960     %-Check numbers of Labels and Values match
0961     if (size(Labels,1)~=size(Values,1))
0962         error('Labels & Values inic_ompatible sizes'), end
0963 end
0964 
0965 
0966 %-Numeric Labels to strings
0967 if isnumeric(Labels)
0968     tmp = Labels; Labels = cell(size(tmp,1),1);
0969     for i=1:prod(size(tmp)), Labels{i}=num2str(tmp(i,:)); end
0970     Labels=char(Labels);
0971 end
0972 
0973 
0974 switch lower(Type), case {'b','bd','b|','y/n'}    %-Process button types
0975 %=======================================================================
0976     
0977     %-Make unique character keys for the Labels, sort DefItem
0978     %---------------------------------------------------------------
0979     nLabels     = size(Labels,1);
0980     [Keys,Labs] = sf_labkeys(Labels);
0981 
0982     if ~isempty(DefItem) & any(DefItem==[1:nLabels])
0983         DefKey = Keys(DefItem);
0984     else
0985         DefItem = 0;
0986         DefKey  = '';
0987     end
0988 
0989     if CmdLine
0990         %-Display question prompt
0991         nic_spm_input('!PrntPrmpt',Prompt,'',Title)
0992         %-Build prompt
0993         %-------------------------------------------------------
0994         if ~isempty(Labs) 
0995             Prmpt = ['[',Keys(1),']',deblank(Labs(1,:)),' '];
0996             for i = 2:nLabels
0997                 Prmpt=[Prmpt,'/ [',Keys(i),']',deblank(Labs(i,:)),' '];
0998             end
0999         else
1000             Prmpt = ['[',Keys(1),'] '];
1001             for i = 2:nLabels, Prmpt=[Prmpt,'/ [',Keys(i),'] ']; end
1002         end
1003         if DefItem
1004             Prmpt = [Prmpt,...
1005                 ' (Default: ',deblank(Labels(DefItem,:)),')'];
1006         end
1007 
1008         %-Ask for user response
1009         %-------------------------------------------------------
1010         if nLabels==1
1011             %-Only one choice - auto-pick & display
1012             k = 1; fprintf('%s: %s\t(only option)',Prmpt,Labels)
1013         else
1014             str = input([Prmpt,'? '],'s');
1015             if isempty(str), str=DefKey; end
1016             while isempty(str) | ~any(lower(Keys)==lower(str(1)))
1017                 if ~isempty(str),fprintf('%c\t!Out of range\n',7),end
1018                 str = input([Prmpt,'? '],'s');
1019                 if isempty(str), str=DefKey; end
1020             end
1021             k = find(lower(Keys)==lower(str(1)));
1022         end
1023         fprintf('\n')
1024 
1025         p = Values(k,:); if ischar(p), p=deblank(p); end
1026 
1027     elseif strcmp(lower(Type),'bd')
1028 
1029         if nLabels>3, error('at most 3 labels for GUI ''db'' type'), end
1030 
1031         tmp = cellstr(Labels);
1032         if DefItem
1033             tmp    = [tmp; tmp(DefItem)];
1034             Prompt = cellstr(Prompt); Prompt=Prompt(:);
1035             Prompt = [Prompt;{' '};...
1036                     {['[default: ',tmp{DefItem},']']}];
1037         else
1038             tmp    = [tmp; tmp(1)];
1039         end
1040 
1041         k = min(find(strcmp(tmp,...
1042             questdlg(Prompt,sprintf('%s%s: %s...',nic_spm('ver'),...
1043                 nic_spm('GetUser',' (%s)'),Title),tmp{:}))));
1044 
1045         p = Values(k,:); if ischar(p), p=deblank(p); end
1046 
1047     else
1048 
1049         Tag = ['GUIinput_',int2str(YPos)];    %-Tag for widgets
1050 
1051         %-Create text and edit control objects
1052         %-'UserData' of prompt contains answer
1053         %-------------------------------------------------------
1054         hPrmpt = uicontrol(Finter,'Style','Text',...
1055             'String',Prompt,...
1056             'Tag',Tag,...
1057             'UserData',[],...
1058             'HorizontalAlignment','Right',...
1059             'Position',PRec);
1060     
1061         if nLabels==1
1062             %-Only one choice - auto-pick
1063             k = 1;
1064         else
1065             %-Draw buttons and process response
1066             dX = RRec(3)/nLabels;
1067             
1068             if TTips, str = ['select with mouse or use kbd: ',...
1069                 sprintf('%c/',Keys(1:end-1)),Keys(end)];
1070             else, str=''; end
1071         
1072             %-Store button # in buttons 'UserData' property
1073             %-Store handle of prompt string in buttons 'Max' property
1074             %-Button callback sets UserData of prompt string to
1075             % number of pressed button
1076             cb = ['set(get(gcbo,''Max''),''UserData'',',...
1077                 'get(gcbo,''UserData''))'];
1078             H = [];
1079             XDisp = [];
1080             for i=1:nLabels
1081                 if i==DefItem
1082                     %-Default button, outline it
1083                     h = uicontrol(Finter,'Style','Frame',...
1084                         'BackGroundColor','k',...
1085                         'ForeGroundColor','k',...
1086                         'Tag',Tag,...
1087                         'Position',...
1088                         [RRec(1)+(i-1)*dX ...
1089                             RRec(2)-1 dX RRec(4)+2]);
1090                     XDisp = (i-1/3)*dX;
1091                     H = [H,h];
1092                 end
1093                 h = uicontrol(Finter,'Style','Pushbutton',...
1094                     'String',deblank(Labels(i,:)),...
1095                     'ToolTipString',str,...
1096                     'Tag',Tag,...
1097                     'Max',hPrmpt,...
1098                     'UserData',i,...
1099                     'BackgroundColor',COLOUR,...
1100                     'Callback',cb,...
1101                     'Position',[RRec(1)+(i-1)*dX+1 ...
1102                             RRec(2) dX-2 RRec(4)]);
1103                 H = [H,h];
1104             end
1105         
1106             %-Figure ContextMenu for shortcuts
1107             hM = nic_spm_input('!InptConMen',Finter,[hPrmpt,H]);
1108 
1109             %-Bring window to fore & jump pointer to default button
1110             [PLoc,cF]=nic_spm_input('!PointerJump',RRec,Finter,XDisp);
1111     
1112             %-Callback for KeyPress, to store valid button # in
1113             % UserData of Prompt, DefItem if (DefItem~=0)
1114             % & return (ASCII-13) is pressed
1115             set(Finter,'KeyPressFcn',...
1116                 ['nic_spm_input(''!ButtonKeyPressFcn'',',...
1117                 'findobj(gcf,''Tag'',''',Tag,''',',...
1118                     '''Style'',''text''),',...
1119                 '''',lower(Keys),''',',num2str(DefItem),',',...
1120                 'get(gcbf,''CurrentCharacter''))'])
1121 
1122             %-Wait for button press, process results
1123             %-----------------------------------------------
1124             waitfor(hPrmpt,'UserData')
1125             if ~ishandle(hPrmpt)
1126                 error(['Input objects cleared whilst ',...
1127                 'waiting for response: Bailing out!'])
1128             end
1129             k = get(hPrmpt,'UserData');
1130             %-Clean up
1131             delete([H,hM]),    set(Finter,'KeyPressFcn','')
1132             nic_spm_input('!PointerJumpBack',PLoc,cF)
1133         end
1134         
1135         %-Display answer
1136         uicontrol(Finter,'Style','Text',...
1137             'String',deblank(Labels(k,:)),...
1138             'Tag',Tag,...
1139             'Horizontalalignment','Center',...
1140             'BackgroundColor',[.7,.7,.7],...
1141             'Position',RRec);
1142         drawnow
1143 
1144         p = Values(k,:); if ischar(p), p=deblank(p); end
1145 
1146     end
1147 
1148 
1149 case {'be1','bn1','bw1','bi1','br1','-n1','-w1'}
1150                                       %-Process button/entry combo types
1151 %=======================================================================
1152 if ischar(DefItem), DefStr=DefItem; else, DefStr=num2str(DefItem); end
1153 if isempty(m), strM=''; else, strM=sprintf(' (<=%d)',m); end
1154 
1155 if CmdLine
1156 
1157     %-Process default item
1158     %---------------------------------------------------------------
1159     if ~isempty(DefItem)
1160         [DefVal,msg] = sf_eEval(DefStr,Type(2),1);
1161         if isstr(DefVal), error(['Invalid DefItem: ',msg]), end
1162         Labels  = strvcat(Labels,DefStr);
1163         Values  = [Values;DefVal];
1164         DefItem = size(Labels,1);
1165     end
1166 
1167     %-Add option to specify...
1168     Labels = strvcat(Labels,'specify...');
1169 
1170     %-Process options
1171     nLabels     = size(Labels,1);
1172     [Keys,Labs] = sf_labkeys(Labels);
1173 
1174     if ~isempty(DefItem), DefKey = Keys(DefItem); else, DefKey = ''; end
1175 
1176     %-Print banner prompt
1177     %---------------------------------------------------------------
1178     nic_spm_input('!PrntPrmpt',Prompt)        %-Display question prompt
1179 
1180 
1181     if Type(1)=='-'        %-No special buttons - go straight to input
1182 
1183         k = size(Labels,1);
1184 
1185     else            %-Offer buttons, default or "specify..."
1186     
1187         %-Build prompt
1188         %-------------------------------------------------------
1189         if ~isempty(Labs) 
1190             Prmpt = ['[',Keys(1),']',deblank(Labs(1,:)),' '];
1191             for i = 2:nLabels
1192                 Prmpt=[Prmpt,'/ [',Keys(i),']',deblank(Labs(i,:)),' '];
1193             end
1194         else
1195             Prmpt = ['[',Keys(1),'] '];
1196             for i = 2:nLabels, Prmpt=[Prmpt,'/ [',Keys(i),'] ']; end
1197         end
1198         if DefItem, Prmpt = [Prmpt,...
1199             ' (Default: ',deblank(Labels(DefItem,:)),')']; end
1200     
1201         %-Ask for user response
1202         %-------------------------------------------------------
1203         if nLabels==1
1204             %-Only one choice - auto-pick & display
1205             k = 1; fprintf('%s: %s\t(only option)',Prmpt,Labels)
1206         else
1207             str = input([Prmpt,'? '],'s');
1208             if isempty(str), str=DefKey; end
1209             while isempty(str) | ~any(lower(Keys)==lower(str(1)))
1210                 if ~isempty(str),fprintf('%c\t!Invalid response\n',7),end
1211                 str = input([Prmpt,'? '],'s');
1212                 if isempty(str), str=DefKey; end
1213             end
1214             k = find(lower(Keys)==lower(str(1)));
1215         end
1216         fprintf('\n')
1217 
1218     end
1219 
1220 
1221     %-Process response: prompt for value if "specify..." option chosen
1222     %===============================================================
1223     if k<size(Labels,1)
1224         p = Values(k,:); if ischar(p), p=deblank(p); end
1225     else
1226 
1227         %-"specify option chosen: ask user to specify
1228         %-------------------------------------------------------
1229         switch lower(Type(2))
1230                 case 's', tstr=' string';        case 'e', tstr='n expression';
1231                 case 'n', tstr=' natural number';case 'w', tstr=' whole number';
1232                 case 'i', tstr='n integer';      case 'r', tstr=' real number';
1233                 otherwise, tstr=''; end
1234         
1235         Prompt = sprintf('%s (a%s%s)',Prompt,tstr,strM);
1236         if ~isempty(DefStr)
1237             Prompt=sprintf('%s\b, default %s)',Prompt,DefStr); end
1238         str = input([Prompt,' : '],'s');
1239         if isempty(str), str=DefStr; end
1240     
1241         %-Eval in Base workspace, catch errors
1242         [p,msg] = sf_eEval(str,Type(2),1,m);
1243         while isstr(p)
1244             nic_spm('Beep'), fprintf('! %s : %s\n',mfilename,msg)
1245             str = input([Prompt,' : '],'s');
1246             if isempty(str), str=DefStr; end
1247             [p,msg] = sf_eEval(str,Type(2),1,m);
1248         end
1249     end
1250 
1251 
1252 else
1253 
1254 
1255     Tag = ['GUIinput_',int2str(YPos)];        %-Tag for widgets
1256     nLabels     = size(Labels,1);            %-#buttons
1257 
1258     %-Create text and edit control objects
1259     %-'UserData' of prompt contains answer
1260     %---------------------------------------------------------------
1261     hPrmpt = uicontrol(Finter,'Style','Text',...
1262         'String',[Prompt,strM],...
1263         'Tag',Tag,...
1264         'UserData',[],...
1265         'HorizontalAlignment','Right',...
1266         'Position',PRec);
1267 
1268     %-Draw buttons & entry widget, & process response
1269     dX = RRec(3)*(2/3)/nLabels;
1270 
1271     %-Store button # in buttons 'UserData'
1272     %-Store handle of prompt string in buttons 'Max' property
1273     %-Callback sets UserData of prompt string to button number.
1274     cb = ['set(get(gcbo,''Max''),''UserData'',get(gcbo,''UserData''))'];
1275     if TTips, str=sprintf('select by mouse or enter value in text widget');
1276         else, str=''; end
1277     H = [];
1278     for i=1:nLabels
1279         h = uicontrol(Finter,'Style','Pushbutton',...
1280             'String',deblank(Labels(i,:)),...
1281             'Max',hPrmpt,...
1282             'ToolTipString',str,...
1283             'Tag',Tag,...
1284             'UserData',i,...
1285             'BackgroundColor',COLOUR,...
1286             'Callback',cb,...
1287             'Position',[RRec(1)+(i-1)*dX+1 RRec(2) dX-2 RRec(4)]);
1288         H = [H,h];
1289     end
1290 
1291     %-Default button surrounding edit widget (if a DefStr given)
1292     %-Callback sets hPrmpt UserData, and EditWidget string, to DefStr
1293     % (Buttons UserData holds handles [hPrmpt,hEditWidget], set later)
1294     cb = ['set(get(gcbo,''UserData'')*[1;0],''UserData'',',...
1295             'get(gcbo,''String'')),',...
1296         'set(get(gcbo,''UserData'')*[0;1],''String'',',...
1297             'get(gcbo,''String''))'];
1298     if ~isempty(DefStr)
1299         hDef = uicontrol(Finter,'Style','PushButton',...
1300             'String',DefStr,...
1301             'ToolTipString',['Click on border to accept ',...
1302                 'default: ' DefStr],...
1303             'Tag',Tag,...
1304             'UserData',[],...
1305             'CallBack',cb,...
1306             'Position',...
1307             [RRec(1)+RRec(3)*(2/3) RRec(2)-2 RRec(3)/3+2 RRec(4)+4]);
1308         H = [H,hDef];
1309     else
1310         hDef = [];
1311     end
1312 
1313     %-Edit widget: Callback puts string into hPrompts UserData
1314     cb = ['set(get(gcbo,''UserData''),''UserData'',get(gcbo,''String''))'];
1315     h = uicontrol(Finter,'Style','Edit',...
1316         'String',DefStr,...
1317         'ToolTipString',str,...
1318         'Tag',Tag,...
1319         'UserData',hPrmpt,...
1320         'CallBack',cb,...
1321         'Horizontalalignment','Center',...
1322         'BackgroundColor',COLOUR,...
1323         'Position',...
1324             [RRec(1)+RRec(3)*(2/3)+2 RRec(2) RRec(3)/3-2 RRec(4)]);
1325     set(hDef,'UserData',[hPrmpt,h])
1326     H = [H,h];
1327 
1328     %-Figure ContextMenu for shortcuts
1329     hM = nic_spm_input('!InptConMen',Finter,[hPrmpt,H]);
1330 
1331     %-Bring window to fore & jump pointer to default button
1332     [PLoc,cF] = nic_spm_input('!PointerJump',RRec,Finter,RRec(3)*0.95);
1333 
1334     %-Setup FigureKeyPressFcn for editing of entry widget without clicking
1335     set(Finter,'KeyPressFcn',[...
1336         'nic_spm_input(''!EditableKeyPressFcn'',',...
1337         'findobj(gcf,''Tag'',''GUIinput_',int2str(YPos),''',',...
1338             '''Style'',''edit''),',...
1339         'get(gcbf,''CurrentCharacter''))'])
1340 
1341 
1342     %-Wait for button press, process results
1343     %---------------------------------------------------------------
1344     waitfor(hPrmpt,'UserData')
1345     if ~ishandle(hPrmpt), error(['Input objects cleared whilst waiting ',...
1346         'for response: Bailing out!']), end
1347     p = get(hPrmpt,'UserData');
1348     if ~isstr(p)
1349         k = p;
1350         p = Values(k,:); if ischar(p), p=deblank(p); end
1351     else
1352         Labels  = strvcat(Labels,'specify...');
1353         k       = size(Labels,1);
1354         [p,msg] = sf_eEval(p,Type(2),1,m);
1355         while isstr(p)
1356             set(H,'Visible','off')
1357             h = uicontrol('Style','Text','String',msg,...
1358                 'Horizontalalignment','Center',...
1359                 'ForegroundColor','r',...
1360                 'Tag',Tag,'Position',RRec);
1361             nic_spm('Beep')
1362             pause(2), delete(h), set(H,'Visible','on')
1363             set(hPrmpt,'UserData','')
1364             waitfor(hPrmpt,'UserData')
1365             if ~ishandle(hPrmpt), error(['Input objects cleared ',...
1366                 'whilst waiting for response: Bailing out!']),end
1367             p = get(hPrmpt,'UserData');
1368             if isstr(p), [p,msg] = sf_eEval(p,Type(2),1,m); end
1369         end
1370     end
1371 
1372     %-Clean up
1373     delete([H,hM]), set(Finter,'KeyPressFcn','')
1374     nic_spm_input('!PointerJumpBack',PLoc,cF)
1375 
1376     %-Display answer
1377     uicontrol(Finter,'Style','Text',...
1378         'String',num2str(p),...
1379         'Tag',Tag,...
1380         'Horizontalalignment','Center',...
1381         'BackgroundColor',[.7,.7,.7],...
1382         'Position',RRec);
1383     drawnow
1384 
1385 end % (if CmdLine)
1386 
1387 
1388 case 'm'                                             %-Process menu type
1389 %=======================================================================
1390     nLabels = size(Labels,1);
1391     if ~isempty(DefItem) & ~any(DefItem==[1:nLabels]), DefItem=[]; end
1392     %-Process pull down menu type
1393     if CmdLine
1394         nic_spm_input('!PrntPrmpt',Prompt)
1395         nLabels = size(Labels,1);
1396         for i = 1:nLabels, fprintf('\t%2d : %s\n',i,Labels(i,:)), end
1397         Prmpt = ['Menu choice (1-',int2str(nLabels),')'];
1398         if DefItem
1399             Prmpt=[Prmpt,' (Default: ',num2str(DefItem),')'];
1400         end
1401 
1402         %-Ask for user response
1403         %-------------------------------------------------------
1404         if nLabels==1
1405             %-Only one choice - auto-pick & display
1406             k = 1;
1407             fprintf('Menu choice: 1 - %s\t(only option)',Labels)
1408         else
1409             k = input([Prmpt,' ? ']);
1410             if DefItem & isempty(k), k=DefItem; end
1411             while isempty(k) | ~any([1:nLabels]==k)
1412                 if ~isempty(k),fprintf('%c\t!Out of range\n',7),end
1413                 k = input([Prmpt,' ? ']);
1414                 if DefItem & isempty(k), k=DefItem; end
1415             end
1416         end
1417         fprintf('\n')
1418     
1419     else
1420 
1421         Tag = ['GUIinput_',int2str(YPos)];    %-Tag for widgets
1422 
1423         if nLabels==1
1424             %-Only one choice - auto-pick
1425             k = 1;
1426         else
1427 
1428             Labs=[repmat(' ',nLabels,2),Labels];
1429             if DefItem
1430                 Labs(DefItem,1)='*';
1431                 H = uicontrol(Finter,'Style','Frame',...
1432                     'BackGroundColor','k',...
1433                     'ForeGroundColor','k',...
1434                     'Position',QRec+[-1,-1,+2,+2]);
1435             else
1436                 H = [];
1437             end
1438             cb = ['if (get(gcbo,''Value'')>1),',...
1439                 'set(gcbo,''UserData'',''Selected''), end'];
1440             hPopUp = uicontrol(Finter,'Style','PopUp',...
1441                 'HorizontalAlignment','Left',...
1442                 'ForegroundColor','k',...
1443                 'BackgroundColor',COLOUR,...
1444                 'String',strvcat([Prompt,'...'],Labs),...
1445                 'Tag',Tag,...
1446                 'UserData',DefItem,...
1447                 'CallBack',cb,...
1448                 'Position',QRec);
1449             if TTips, set(hPopUp,'ToolTipString',['select with ',...
1450                 'mouse or type option number (1-',...
1451                 num2str(nLabels),') & press return']), end
1452     
1453             %-Figure ContextMenu for shortcuts
1454             hM = nic_spm_input('!InptConMen',Finter,[hPopUp,H]);
1455 
1456             %-Bring window to fore & jump pointer to menu widget
1457             [PLoc,cF] = nic_spm_input('!PointerJump',RRec,Finter);
1458     
1459             %-Callback for KeyPresses
1460             cb=['nic_spm_input(''!PullDownKeyPressFcn'',',...
1461                 'findobj(gcf,''Tag'',''',Tag,'''),',...
1462                 'get(gcf,''CurrentCharacter''))'];
1463             set(Finter,'KeyPressFcn',cb)
1464 
1465             %-Wait for menu selection
1466             %-----------------------------------------------
1467             waitfor(hPopUp,'UserData')
1468             if ~ishandle(hPopUp), error(['Input object cleared ',...
1469                 'whilst waiting for response: Bailing out!']),end
1470             k = get(hPopUp,'Value')-1;
1471 
1472             %-Clean up
1473             delete([H,hM]), set(Finter,'KeyPressFcn','')
1474             set(hPopUp,'Style','Text',...
1475                 'Horizontalalignment','Center',...
1476                 'String',deblank(Labels(k,:)),...
1477                 'BackgroundColor',[.7,.7,.7])
1478             nic_spm_input('!PointerJumpBack',PLoc,cF)
1479         end
1480     
1481         %-Display answer
1482         uicontrol(Finter,'Style','Text',...
1483             'String',deblank(Labels(k,:)),...
1484             'Tag',Tag,...
1485             'Horizontalalignment','Center',...
1486             'BackgroundColor',[.7,.7,.7],...
1487             'Position',QRec);
1488         drawnow
1489     end
1490 
1491     p = Values(k,:); if ischar(p), p=deblank(p); end
1492 
1493 otherwise, error('unrecognised type')
1494 end % (switch lower(Type) within case {'b','b|','y/n'})
1495 
1496 
1497 %-Log the transaction & return response
1498 %-----------------------------------------------------------------------
1499 if exist('nic_spm_log')==2
1500     if iscellstr(Prompt), Prompt=Prompt{1}; end
1501     nic_spm_log([mfilename,' : ',Prompt,': (',deblank(Labels(k,:)),')'],p); end
1502 varargout = {p,YPos};
1503 
1504 
1505 
1506 case {'m!','b!'}                          %-GUI PullDown/Buttons utility
1507 %=======================================================================
1508 % H = spm_input(Prompt,YPos,'p',Labels,cb,UD,XCB)
1509 %-Condition arguments
1510 if nargin<7, XCB    = 0;  else, XCB    = varargin{7}; end
1511 if nargin<6, UD     = []; else, UD     = varargin{6}; end
1512 if nargin<5, cb     = ''; else, cb     = varargin{5}; end
1513 if nargin<4, Labels = []; else, Labels = varargin{4}; end
1514 
1515 if CmdLine, error('Can''t do CmdLine GUI utilities!'), end
1516 if isempty(cb), cb = 'disp(''(CallBack not set)'')'; end
1517 if ischar(cb), cb = cellstr(cb); end
1518 if length(cb)>1 & strcmp(lower(Type),'m!'), XCB=1; end
1519 
1520 if iscellstr(Labels), Labels=char(Labels); end
1521 %-Convert Labels "option" string to string matrix if required
1522 if any(Labels=='|')
1523     OptStr=Labels;
1524     BarPos=find([OptStr=='|',1]);
1525     Labels=OptStr(1:BarPos(1)-1);
1526     for Bar = 2:sum(OptStr=='|')+1
1527         Labels=strvcat(Labels,OptStr(BarPos(Bar-1)+1:BarPos(Bar)-1));
1528     end
1529 end
1530 
1531 %-Check #CallBacks
1532 if ~( length(cb)==1 | (length(cb)==size(Labels,1)) )
1533     error('Labels & Callbacks size mismatch'), end
1534 
1535 
1536 %-Draw Prompt
1537 %-----------------------------------------------------------------------
1538 Tag = ['GUIinput_',int2str(YPos)];            %-Tag for widgets
1539 
1540 if ~isempty(Prompt)
1541     uicontrol(Finter,'Style','Text',...
1542         'String',Prompt,...
1543         'Tag',Tag,...
1544         'HorizontalAlignment','Right',...
1545         'Position',PRec)
1546     Rec = RRec;
1547 else
1548     Rec = QRec;
1549 end
1550 
1551 
1552 %-Sort out UserData for extended callbacks (handled by spm_input('!m_cb')
1553 %-----------------------------------------------------------------------
1554 if XCB, if iscell(UD), UD={UD}; end, UD = struct('UD',UD,'cb',{cb}); end
1555 
1556 
1557 %-Draw PullDown or Buttons
1558 %-----------------------------------------------------------------------
1559 switch lower(Type), case 'm!'
1560     if XCB, UD.cb=cb; cb = {'nic_spm_input(''!m_cb'')'}; end
1561     H = uicontrol(Finter,'Style','PopUp',...
1562         'HorizontalAlignment','Left',...
1563         'ForegroundColor','k',...
1564         'BackgroundColor',COLOUR,...
1565         'String',Labels,...
1566         'Tag',Tag,...
1567         'UserData',UD,...
1568         'CallBack',char(cb),...
1569         'Position',Rec);
1570 
1571 case 'b!'
1572     nLabels = size(Labels,1);
1573     dX = Rec(3)/nLabels;
1574 
1575     H = [];
1576     for i=1:nLabels
1577         if length(cb)>1, tcb=cb(i); else, tcb=cb; end
1578         if XCB, UD.cb=tcb; tcb = {'nic_spm_input(''!m_cb'')'}; end
1579         h = uicontrol(Finter,'Style','Pushbutton',...
1580             'String',deblank(Labels(i,:)),...
1581             'ToolTipString','',...
1582             'Tag',Tag,...
1583             'UserData',UD,...
1584             'BackgroundColor',COLOUR,...
1585             'Callback',char(tcb),...
1586             'Position',[Rec(1)+(i-1)*dX+1 ...
1587                     Rec(2) dX-2 Rec(4)]);
1588         H = [H,h];
1589     end
1590 
1591 
1592 end
1593 
1594 
1595 %-Bring window to fore & jump pointer to menu widget
1596 [PLoc,cF] = nic_spm_input('!PointerJump',RRec,Finter);
1597 
1598 varargout = {H};
1599 
1600 
1601 
1602 case {'d','d!'}                                        %-Display message
1603 %=======================================================================
1604 %-Condition arguments
1605 if nargin<4, Label=''; else, Label=varargin{4}; end
1606 
1607 if CmdLine & strcmp(lower(Type),'d')
1608     fprintf('\n     +-%s%s+',Label,repmat('-',1,57-length(Label)))
1609     Prompt = [Prompt,' '];
1610     while length(Prompt)>0
1611         tmp = length(Prompt);
1612         if tmp>56, tmp=min([max(find(Prompt(1:56)==' ')),56]); end
1613         fprintf('\n     | %s%s |',Prompt(1:tmp),repmat(' ',1,56-tmp))
1614         Prompt(1:tmp)=[];
1615     end
1616     fprintf('\n     +-%s+\n',repmat('-',1,57))
1617 elseif ~CmdLine
1618     if ~isempty(Label), Prompt = [Label,': ',Prompt]; end
1619     figure(Finter)
1620     %-Create text axes and edit control objects
1621     %---------------------------------------------------------------
1622     h = uicontrol(Finter,'Style','Text',...
1623         'String',Prompt(1:min(length(Prompt),56)),...
1624         'FontWeight','bold',...
1625         'Tag',['GUIinput_',int2str(YPos)],...
1626         'HorizontalAlignment','Left',...
1627         'ForegroundColor','k',...
1628         'UserData',Prompt,...
1629         'Position',QRec);
1630     if length(Prompt)>56
1631         pause(1)
1632         set(h,'ToolTipString',Prompt)
1633         nic_spm_input('!dScroll',h)
1634         uicontrol(Finter,'Style','PushButton','String','>',...
1635             'ToolTipString','press to scroll message',...
1636             'Tag',['GUIinput_',int2str(YPos)],...
1637             'UserData',h,...
1638             'CallBack',[...
1639              'set(gcbo,''Visible'',''off''),',...
1640              'nic_spm_input(''!dScroll'',get(gcbo,''UserData'')),',...
1641              'set(gcbo,''Visible'',''on'')'],...
1642             'Position',[QRec(1)+QRec(3)-10,QRec(2),15,QRec(4)]);
1643     end
1644 end
1645 if nargout>0, varargout={[],YPos}; end
1646 
1647 
1648 
1649 %=======================================================================
1650 % U T I L I T Y   F U N C T I O N S
1651 %=======================================================================
1652 
1653 case '!colour'
1654 %=======================================================================
1655 % colour = spm_input('!Colour')
1656 varargout = {COLOUR};
1657 
1658 
1659 case '!icond'
1660 %=======================================================================
1661 % [iCond,msg] = spm_input('!iCond',str,n,m)
1662 % Parse condition indicator spec strings:
1663 %    '2 3 2 3', '0 1 0 1', '2323', '0101', 'abab', 'R A R A'
1664 if nargin<4, m=Inf; else, m=varargin{4}; end
1665 if nargin<3, n=NaN; else, n=varargin{3}; end
1666 if any(isnan(n(:)))
1667     n=Inf;
1668 elseif (length(n(:))==2 & ~any(n==1)) | length(n(:))>2
1669     error('condition input can only do vectors')
1670 end
1671 if nargin<2, i=''; else, i=varargin{2}; end
1672 if isempty(i), varargout={[],'empty input'}; return, end
1673 msg = ''; i=i(:)';
1674 
1675 if ischar(i)
1676     if i(1)=='0' & all(ismember(unique(i(:)),setstr(abs('0'):abs('9'))))
1677         %-Leading zeros in a digit list
1678         msg = sprintf('%s expanded',i);
1679         z = min(find([diff(i=='0'),1]));
1680         i = [zeros(1,z), nic_spm_input('!iCond',i(z+1:end))'];
1681     else
1682         %-Try an eval, for functions & string #s
1683         i = evalin('base',['[',i,']'],'i');
1684     end
1685 end
1686 
1687 if ischar(i)
1688     %-Evaluation error from above: see if it's an 'abab' or 'a b a b' type:
1689     [c,null,i] = unique(lower(i(~isspace(i))));
1690     if all(ismember(c,setstr(abs('a'):abs('z'))))
1691         %-Map characters a-z to 1-26, but let 'r' be zero (rest)
1692         tmp = c-'a'+1; tmp(tmp=='r'-'a'+1)=0;
1693         i   = tmp(i);
1694         msg = [sprintf('[%s] mapped to [',c),...
1695             sprintf('%d,',tmp(1:end-1)),...
1696             sprintf('%d',tmp(end)),']'];
1697     else
1698         i = '!'; msg = 'evaluation error';
1699     end
1700 elseif ~all(floor(i(:))==i(:))
1701     i = '!'; msg = 'must be integers';
1702 elseif length(i)==1 & prod(n)>1
1703     msg = sprintf('%d expanded',i);
1704     i = floor(i./10.^[floor(log10(i)+eps):-1:0]);
1705     i = i-[0,10*i(1:end-1)];
1706 end
1707 
1708 %-Check size of i & #conditions
1709 if ~isstr(i), [i,msg] = sf_SzChk(i,n,msg); end
1710 if ~isstr(i) & isfinite(m) & length(unique(i))~=m
1711     i = '!'; msg = sprintf('%d conditions required',m);
1712 end
1713 
1714 varargout = {i,msg};
1715 
1716 
1717 case '!inptconmen'
1718 %=======================================================================
1719 % hM = spm_input('!InptConMen',Finter,H)
1720 if nargin<3, H=[]; else, H=varargin{3}; end
1721 if nargin<2, varargout={[]}; else, Finter=varargin{2}; end
1722 hM = uicontextmenu('Parent',Finter);
1723 uimenu(hM,'Label','help on nic_spm_input',...
1724     'CallBack','nic_spm_help(''nic_spm_input.m'')')
1725 if Conic_rash
1726     uimenu(hM,'Label','crash out','Separator','on',...
1727         'CallBack','delete(get(gcbo,''UserData''))',...
1728         'UserData',[hM,H])
1729 end
1730 
1731 set(Finter,'UIContextMenu',hM)
1732 
1733 varargout={hM};
1734 
1735 
1736 case '!cmdline'
1737 %=======================================================================
1738 % [CmdLine,YPos] = spm_input('!CmdLine',YPos)
1739 %-Sorts out whether to use CmdLine or not & canonicalises YPos
1740 if nargin<2, YPos=''; else, YPos=varargin{2}; end
1741 if isempty(YPos), YPos='+1'; end
1742 
1743 CmdLine = [];
1744 
1745 %-Special YPos specifications
1746 if ischar(YPos)
1747     if(YPos(1)=='!'), CmdLine=0; YPos(1)=[]; end
1748 elseif YPos==0
1749     CmdLine=1;
1750 elseif YPos<0
1751     CmdLine=0;
1752     YPos=-YPos;
1753 end
1754 
1755 CmdLine = nic_spm('CmdLine',CmdLine);
1756 if CmdLine, YPos=0; end
1757 
1758 varargout = {CmdLine,YPos};
1759 
1760 
1761 case '!getwin'
1762 %=======================================================================
1763 % Finter = spm_input('!GetWin',F)
1764 %-Locate (or create) figure to work in (Don't use 'Tag'ged figs)
1765 if nargin<2, F='Interactive'; else, F=varargin{2}; end
1766 Finter = nic_spm_figure('FindWin',F);
1767 if isempty(Finter)
1768     if any(get(0,'Children'))
1769         if isempty(get(gcf,'Tag')), Finter = gcf;
1770         else, Finter = nic_spm('CreateIntWin'); end
1771     else, Finter = nic_spm('CreateIntWin'); end
1772 end
1773 varargout = {Finter};
1774 
1775 
1776 case '!pointerjump'
1777 %=======================================================================
1778 % [PLoc,cF] = spm_input('!PointerJump',RRec,F,XDisp)
1779 %-Raise window & jump pointer over question
1780 if nargin<4, XDisp=[]; else, XDisp=varargin{4}; end
1781 if nargin<3, F='Interactive'; else, F=varargin{3}; end
1782 if nargin<2, error('Insufficient arguments'), else, RRec=varargin{2}; end
1783 F = nic_spm_figure('FindWin',F);
1784 PLoc = get(0,'PointerLocation');
1785 cF   = get(0,'CurrentFigure');
1786 if ~isempty(F)
1787     figure(F)
1788     FRec = get(F,'Position');
1789     if isempty(XDisp), XDisp=RRec(3)*4/5; end
1790     if PJump, set(0,'PointerLocation',...
1791         floor([(FRec(1)+RRec(1)+XDisp), (FRec(2)+RRec(2)+RRec(4)/3)]));
1792     end
1793 end
1794 varargout = {PLoc,cF};
1795 
1796 
1797 case '!pointerjumpback'
1798 %=======================================================================
1799 % spm_input('!PointerJumpBack',PLoc,cF)
1800 %-Replace pointer and reset CurrentFigure back
1801 if nargin<4, cF=[]; else, F=varargin{3}; end
1802 if nargin<2, error('Insufficient arguments'), else, PLoc=varargin{2}; end
1803 if PJump, set(0,'PointerLocation',PLoc), end
1804 cF = nic_spm_figure('FindWin',cF);
1805 if ~isempty(cF), set(0,'CurrentFigure',cF); end
1806 
1807 
1808 case '!prntprmpt'
1809 %=======================================================================
1810 % spm_input('!PrntPrmpt',Prompt,TipStr,Title)
1811 %-Print prompt for CmdLine questioning
1812 if nargin<4, Title  = ''; else, Title  = varargin{4}; end
1813 if nargin<3, TipStr = ''; else, TipStr = varargin{3}; end
1814 if nargin<2, Prompt = ''; else, Prompt = varargin{2}; end
1815 if isempty(Prompt), Prompt='Enter an expression'; end
1816 
1817 Prompt = cellstr(Prompt);
1818 
1819 if ~isempty(TipStr)
1820   tmp    = 8 + length(Prompt{end}) + length(TipStr);
1821   if tmp < 62
1822     TipStr = sprintf('%s(%s)',repmat(' ',1,70-tmp),TipStr);
1823   else
1824     TipStr = sprintf('\n%s(%s)',repmat(' ',1,max(0,70-length(TipStr))),TipStr);
1825   end
1826 end
1827 
1828 if isempty(Title)
1829     fprintf('\n%s\n',repmat('~',1,72))
1830 else
1831     fprintf('\n= %s %s\n',Title,repmat('~',1,72-length(Title)-3))
1832 end
1833 fprintf('\t%s',Prompt{1})
1834 for i=2:prod(size(Prompt)), fprintf('\n\t%s',Prompt{i}), end
1835 fprintf('%s\n%s\n',TipStr,repmat('~',1,72))
1836 
1837 
1838 case '!inputrects'
1839 %=======================================================================
1840 % [Frec,QRec,PRec,RRec,Sz,Se] = spm_input('!InputRects',YPos,rec,F)
1841 if nargin<4, F='Interactive'; else, F=varargin{4}; end
1842 if nargin<3, rec=''; else, rec=varargin{3}; end
1843 if nargin<2, YPos=1; else, YPos=varargin{2}; end
1844 F = nic_spm_figure('FindWin',F);
1845 if isempty(F), error('Figure not found'), end
1846 
1847 Units = get(F,'Units');
1848 set(F,'Units','pixels')
1849 FRec = get(F,'Position');
1850 set(F,'Units',Units);
1851 Xdim = FRec(3); Ydim = FRec(4);
1852 
1853 WS   = nic_spm('WinScale');
1854 Sz   = round(22*min(WS));    %-Height
1855 Pd   = Sz/2;            %-Pad
1856 Se   = 2*round(25*min(WS)/2);    %-Seperation
1857 Yo   = round(2*min(WS));    %-Y offset for responses
1858 
1859 a = 5.5/10;
1860 y = Ydim - Se*YPos;
1861 QRec   = [Pd            y         Xdim-2*Pd        Sz]; %-Question
1862 PRec   = [Pd            y     floor(a*Xdim)-2*Pd   Sz]; %-Prompt
1863 RRec   = [ceil(a*Xdim)  y+Yo  floor((1-a)*Xdim)-Pd Sz]; %-Response
1864 % MRec = [010           y         Xdim-50          Sz]; %-Menu PullDown
1865 % BRec = MRec + [Xdim-50+1, 0+1, 50-Xdim+30, 0];        %-Menu PullDown OK butt
1866 
1867 if ~isempty(rec)
1868     varargout = {eval(rec)};
1869 else
1870     varargout = {FRec,QRec,PRec,RRec,Sz,Se};
1871 end
1872 
1873 
1874 case '!deleteinputobj'
1875 %=======================================================================
1876 % spm_input('!DeleteInputObj',F)
1877 if nargin<2, F='Interactive'; else, F=varargin{2}; end
1878 h = nic_spm_input('!FindInputObj',F);
1879 delete(h(h>0))
1880 
1881 
1882 case {'!currentpos','!findinputobj'}
1883 %=======================================================================
1884 % [CPos,hCPos] = spm_input('!CurrentPos',F)
1885 % h            = spm_input('!FindInputObj',F)
1886 % hPos contains handles: Columns contain handles corresponding to Pos
1887 if nargin<2, F='Interactive'; else, F=varargin{2}; end
1888 F = nic_spm_figure('FindWin',F);
1889 
1890 %-Find tags and YPos positions of 'GUIinput_' 'Tag'ged objects
1891 H    = [];
1892 YPos = [];
1893 for h = get(F,'Children')'
1894     tmp = get(h,'Tag');
1895     if ~isempty(tmp)
1896         if strcmp(tmp(1:min(length(tmp),9)),'GUIinput_')
1897             H    = [H, h];
1898             YPos = [YPos, eval(tmp(10:end))];
1899         end
1900     end
1901 end
1902 
1903 switch lower(Type), case '!findinputobj'
1904     varargout = {H};
1905 case '!currentpos'
1906     if nargout<2
1907         varargout = {max(YPos),[]};
1908     elseif isempty(H)
1909         varargout = {[],[]};
1910     else
1911         %-Sort out
1912         tmp     = sort(YPos);
1913         CPos    = tmp(find([1,diff(tmp)]));
1914         nPos    = length(CPos);
1915         nPerPos = diff(find([1,diff(tmp),1]));
1916         hCPos   = zeros(max(nPerPos),nPos);
1917         for i = 1:nPos
1918             hCPos(1:nPerPos(i),i) = H(YPos==CPos(i))';
1919         end
1920         varargout = {CPos,hCPos};
1921     end
1922 end
1923 
1924 case '!nextpos'
1925 %=======================================================================
1926 % [NPos,CPos,hCPos] = spm_input('!NextPos',YPos,F,CmdLine)
1927 %-Return next position to use
1928 if nargin<3, F='Interactive'; else, F=varargin{3}; end
1929 if nargin<2, YPos='+1'; else, YPos=varargin{2}; end
1930 if nargin<4, [CmdLine,YPos]=nic_spm_input('!CmdLine',YPos);
1931     else, CmdLine=varargin{4}; end
1932 
1933 F = nic_spm_figure('FindWin',F);
1934 
1935 %-Get current positions
1936 if nargout<3
1937     CPos = nic_spm_input('!CurrentPos',F);
1938     hCPos = [];
1939 else
1940     [CPos,hCPos] = nic_spm_input('!CurrentPos',F);
1941 end
1942 
1943 if CmdLine
1944     NPos = 0;
1945 else
1946     MPos = nic_spm_input('!MaxPos',F);
1947     if ischar(YPos)
1948         %-Relative YPos
1949         %-Strip any '!' prefix from YPos
1950         if(YPos(1)=='!'), YPos(1)=[]; end
1951         if strnic_mp(YPos,'_',1)
1952             %-YPos='_' means bottom
1953             YPos=eval(['MPos+',YPos(2:end)],'MPos');
1954         else
1955             YPos = max([0,CPos])+eval(YPos);
1956         end
1957     else
1958         %-Absolute YPos
1959         YPos=abs(YPos);
1960     end
1961     NPos = min(max(1,YPos),MPos);
1962 end
1963 varargout = {NPos,CPos,hCPos};
1964 
1965 case '!setnextpos'
1966 %=======================================================================
1967 % NPos = spm_input('!SetNextPos',YPos,F,CmdLine)
1968 %-Set next position to use
1969 if nargin<3, F='Interactive'; else, F=varargin{3}; end
1970 if nargin<2, YPos='+1'; else, YPos=varargin{2}; end
1971 if nargin<4, [CmdLine,YPos]=nic_spm_input('!CmdLine',YPos);
1972     else, CmdLine=varargin{4}; end
1973 
1974 %-Find out which Y-position to use
1975 [NPos,CPos,hCPos] = nic_spm_input('!NextPos',YPos,F,CmdLine);
1976 
1977 %-Delete any previous inputs using positions NPos and after
1978 if any(CPos>=NPos), h=hCPos(:,CPos>=NPos); delete(h(h>0)), end
1979 
1980 varargout = {NPos};
1981 
1982 case '!maxpos'
1983 %=======================================================================
1984 % MPos = spm_input('!MaxPos',F,FRec3)
1985 %
1986 if nargin<3
1987     if nargin<2, F='Interactive'; else, F=varargin{2}; end
1988     F = nic_spm_figure('FindWin',F);
1989     if isempty(F)
1990         FRec3=nic_spm('WinSize','Interactive')*[0;0;0;1];
1991     else
1992         %-Get figure size
1993         Units = get(F,'Units');
1994         set(F,'Units','pixels')
1995         FRec3 = get(F,'Position')*[0;0;0;1];
1996         set(F,'Units',Units);
1997     end
1998 end
1999 
2000 Se   = round(25*min(nic_spm('WinScale')));
2001 MPos = floor((FRec3-5)/Se);
2002 
2003 varargout = {MPos};
2004 
2005 
2006 case '!editablekeypressfcn'
2007 %=======================================================================
2008 % spm_input('!EditableKeyPressFcn',h,ch,hPrmpt)
2009 if nargin<2, error('Insufficient arguments'), else, h=varargin{2}; end
2010 if isempty(h), set(gcbf,'KeyPressFcn','','UserData',[]), return, end
2011 if nargin<3, ch=get(get(h,'Parent'),'CurrentCharacter'); else, ch=varargin{3};end
2012 if nargin<4, hPrmpt=get(h,'UserData'); else, hPrmpt=varargin{4}; end
2013 
2014 tmp = get(h,'String');
2015 if isempty(tmp), tmp=''; end
2016 if iscellstr(tmp) & length(tmp)==1; tmp=tmp{:}; end
2017 
2018 if isempty(ch)                    %- shift / control / &c. pressed
2019     return
2020 elseif any(abs(ch)==[32:126])            %-Character
2021     if iscellstr(tmp), return, end
2022     tmp = [tmp, ch];
2023 elseif abs(ch)==21                %- ^U - kill
2024     tmp = '';
2025 elseif any(abs(ch)==[8,127])            %-BackSpace or Delete
2026     if iscellstr(tmp), return, end
2027     if length(tmp), tmp(length(tmp))=''; end
2028 elseif abs(ch)==13                %-Return pressed
2029     if ~isempty(tmp)
2030         set(hPrmpt,'UserData',get(h,'String'))
2031     end
2032     return
2033 else
2034     %-Illegal character
2035     return
2036 end
2037 set(h,'String',tmp)
2038 
2039 
2040 case '!buttonkeypressfcn'
2041 %=======================================================================
2042 % spm_input('!ButtonKeyPressFcn',h,Keys,DefItem,ch)
2043 %-Callback for KeyPress, to store valid button # in UserData of Prompt,
2044 % DefItem if (DefItem~=0) & return (ASCII-13) is pressed
2045 
2046 %-Condition arguments
2047 if nargin<2, error('Insufficient arguments'), else, h=varargin{2}; end
2048 if isempty(h), set(gcf,'KeyPressFcn','','UserData',[]), return, end
2049 if nargin<3, error('Insufficient arguments'); else, Keys=varargin{3}; end
2050 if nargin<4, DefItem=0; else, DefItem=varargin{4}; end
2051 if nargin<5, ch=get(gcf,'CurrentCharacter'); else, ch=varargin{5}; end
2052 
2053 if isempty(ch)
2054     %- shift / control / &c. pressed
2055     return
2056 elseif (DefItem & ch==13)
2057     But = DefItem;
2058 else
2059     But = find(lower(ch)==lower(Keys));
2060 end
2061 if ~isempty(But), set(h,'UserData',But), end
2062 
2063 
2064 case '!pulldownkeypressfcn'
2065 %=======================================================================
2066 % spm_input('!PullDownKeyPressFcn',h,ch,DefItem)
2067 if nargin<2, error('Insufficient arguments'), else, h=varargin{2}; end
2068 if isempty(h), set(gcf,'KeyPressFcn',''), return, end
2069 if nargin<3, ch=get(get(h,'Parent'),'CurrentCharacter'); else, ch=varargin{3};end
2070 if nargin<4, DefItem=get(h,'UserData'); else, ch=varargin{4}; end
2071 
2072 Pmax = get(h,'Max');
2073 Pval = get(h,'Value');
2074 
2075 if Pmax==1, return, end
2076 
2077 if isempty(ch)
2078     %- shift / control / &c. pressed
2079     return
2080 elseif abs(ch)==13
2081     if Pval==1
2082         if DefItem, set(h,'Value',max(2,min(DefItem+1,Pmax))), end
2083     else
2084         set(h,'UserData','Selected')
2085     end
2086 elseif any(ch=='bpu')
2087     %-Move "b"ack "u"p to "p"revious entry
2088     set(h,'Value',max(2,Pval-1))
2089 elseif any(ch=='fnd')
2090     %-Move "f"orward "d"own to "n"ext entry
2091     set(h,'Value',min(Pval+1,Pmax))
2092 elseif any(ch=='123456789')
2093     %-Move to entry n
2094     set(h,'Value',max(2,min(eval(ch)+1,Pmax)))
2095 else
2096     %-Illegal character
2097 end
2098 
2099 
2100 case '!m_cb'     %-CallBack handler for extended CallBack 'p'ullDown type
2101 %=======================================================================
2102 % spm_input('!m_cb')
2103 
2104 %-Get PopUp handle and value
2105 h   = gcbo;
2106 n   = get(h,'Value');
2107 
2108 %-Get PopUp's UserData, check cb and UD fields exist, extract cb & UD
2109 tmp = get(h,'UserData');
2110 if ~(isfield(tmp,'cb') & isfield(tmp,'UD'))
2111     error('Invalid UserData structure for nic_spm_input extended callback')
2112 end
2113 cb  = tmp.cb;
2114 UD  = tmp.UD;
2115 
2116 %-Evaluate appropriate CallBack string (ignoring any return arguments)
2117 % NB: Using varargout={eval(cb{n})}; gives an error if the CallBack
2118 % has no return arguments!
2119 if length(cb)==1, eval(char(cb)); else, eval(cb{n}); end
2120 
2121 
2122 case '!dscroll'
2123 %=======================================================================
2124 % spm_input('!dScroll',h,Prompt)
2125 %-Scroll text in object h
2126 if nargin<2, return, else, h=varargin{2}; end
2127 if nargin<3, Prompt = get(h,'UserData'); else, Prompt=varargin{3}; end
2128 tmp = Prompt;
2129 if length(Prompt)>56
2130     while length(tmp)>56
2131         tic, while(toc<0.1), pause(0.05), end
2132         tmp(1)=[];
2133         set(h,'String',tmp(1:min(length(tmp),56)))
2134     end
2135     pause(1)
2136     set(h,'String',Prompt(1:min(length(Prompt),56)))
2137 end
2138 
2139 
2140 otherwise
2141 %=======================================================================
2142 error(['Invalid type/action: ',Type])
2143 
2144 
2145 %=======================================================================
2146 end % (case lower(Type))
2147 
2148 
2149 %=======================================================================
2150 %- S U B - F U N C T I O N S
2151 %=======================================================================
2152 
2153 function [Keys,Labs] = sf_labkeys(Labels)
2154 %=======================================================================
2155 %-Make unique character keys for the Labels, ignoring case
2156 if nargin<1, error('insufficient arguments'), end
2157 if iscellstr(Labels), Labels = char(Labels); end
2158 if isempty(Labels), Keys=''; Labs=''; return, end
2159 
2160 Keys=Labels(:,1)';
2161 nLabels = size(Labels,1);
2162 if any(~diff(abs(sort(lower(Keys)))))
2163     if nLabels<10
2164         Keys = sprintf('%d',[1:nLabels]);
2165     elseif NoLables<=26
2166         Keys = sprintf('%c',abs('a')+[0:nLabels-1]);
2167     else
2168         error('Too many buttons!')
2169     end
2170     Labs = Labels;
2171 else
2172     Labs = Labels(:,2:end);
2173 end
2174 
2175 
2176 function [p,msg] = sf_eEval(str,Type,n,m)
2177 %=======================================================================
2178 %-Evaluation and error trapping of typed input
2179 if nargin<4, m=[]; end
2180 if nargin<3, n=[]; end
2181 if nargin<2, Type='e'; end
2182 if nargin<1, str=''; end
2183 if isempty(str), p='!'; msg='empty input'; return, end
2184 switch lower(Type)
2185 case 's'
2186     p = str; msg = '';
2187 case 'e'
2188     p = evalin('base',['[',str,']'],'''!''');
2189     if isstr(p)
2190         msg = 'evaluation error';
2191     else
2192         [p,msg] = sf_SzChk(p,n);
2193     end
2194 case 'n'
2195     p = evalin('base',['[',str,']'],'''!''');
2196     if isstr(p)
2197         msg = 'evaluation error';
2198     elseif any(floor(p(:))~=p(:)|p(:)<1)|~isreal(p)
2199         p='!'; msg='natural number(s) required';
2200     elseif ~isempty(m) & any(p(:)>m)
2201         p='!'; msg=['max value is ',num2str(m)];
2202     else
2203         [p,msg] = sf_SzChk(p,n);
2204     end
2205 case 'w'
2206     p = evalin('base',['[',str,']'],'''!''');
2207     if isstr(p)
2208         msg = 'evaluation error';
2209     elseif any(floor(p(:))~=p(:)|p(:)<0)|~isreal(p)
2210         p='!'; msg='whole number(s) required';
2211     elseif ~isempty(m) & any(p(:)>m)
2212         p='!'; msg=['max value is ',num2str(m)];
2213     else
2214         [p,msg] = sf_SzChk(p,n);
2215     end
2216 case 'i'
2217     p = evalin('base',['[',str,']'],'''!''');
2218     if isstr(p)
2219         msg = 'evaluation error';
2220     elseif any(floor(p(:))~=p(:))|~isreal(p)
2221         p='!'; msg='integer(s) required';
2222     else
2223         [p,msg] = sf_SzChk(p,n);
2224     end
2225 case 'p'
2226     p = evalin('base',['[',str,']'],'''!''');
2227     if isstr(p)
2228         msg = 'evaluation error';
2229     elseif length(setxor(p(:)',m))
2230         p='!'; msg='invalid permutation';
2231     else
2232         [p,msg] = sf_SzChk(p,n);
2233     end
2234 case 'r'
2235     p = evalin('base',['[',str,']'],'''!''');
2236     if isstr(p)
2237         msg = 'evaluation error';
2238     elseif ~isreal(p)
2239         p='!'; msg='real number(s) required';
2240     elseif ~isempty(m) & ( max(p)>max(m) | min(p)<min(m) )
2241         p='!'; msg=sprintf('real(s) in [%g,%g] required',min(m),max(m));
2242     else
2243         [p,msg] = sf_SzChk(p,n);
2244     end
2245 case 'c'
2246     if isempty(m), m=Inf; end
2247     [p,msg] = nic_spm_input('!iCond',str,n,m);
2248 case 'x'
2249     X = m;            %-Design matrix/space-structure
2250     if isempty(n), n=1; end
2251 
2252     %-Sort out contrast matrix dimensions (contrast vectors in rows)
2253     if length(n)==1, n=[n,Inf]; else, n=reshape(n(1:2),1,2); end
2254     if ~isempty(X)        % - override n(2) w/ design column dimension
2255         n(2) = nic_spm_SpUtil('size',X,2);
2256     end
2257 
2258     p = evalin('base',['[',str,']'],'''!''');
2259     if isstr(p)
2260         msg = 'evaluation error';
2261     else
2262         if isfinite(n(2)) & size(p,2)<n(2)
2263             tmp = n(2) -size(p,2);
2264             p   = [p, zeros(size(p,1),tmp)];
2265             if size(p,1)>1, str=' columns'; else, str='s'; end
2266             msg = sprintf('right padded with %d zero%s',tmp,str);
2267         else
2268             msg = '';
2269         end
2270 
2271         if size(p,2)>n(2)
2272             p='!'; msg=sprintf('too long - only %d prams',n(2));
2273         elseif isfinite(n(1)) & size(p,1)~=n(1)
2274             p='!';
2275             if n(1)==1, msg='vector required';
2276                 else, msg=sprintf('%d contrasts required',n(1)); end
2277         elseif ~isempty(X) & ~nic_spm_SpUtil('allCon',X,p')
2278             p='!'; msg='invalid contrast';
2279         end
2280     end
2281 
2282 otherwise
2283     error('unrecognised type');
2284 end
2285 
2286 
2287 function str = sf_SzStr(n,l)
2288 %=======================================================================
2289 %-Size info string constuction
2290 if nargin<2, l=0; else, l=1; end
2291 if nargin<1, error('insufficient arguments'), end
2292 if isempty(n), n=NaN; end
2293 n=n(:); if length(n)==1, n=[n,1]; end, dn=length(n);
2294 if any(isnan(n)) | (prod(n)==1 & dn<=2) | (dn==2 & min(n)==1 & isinf(max(n)))
2295     str = ''; lstr = '';
2296 elseif dn==2 & min(n)==1
2297     str = sprintf('[%d]',max(n));    lstr = [str,'-vector'];
2298 elseif dn==2 & sum(isinf(n))==1
2299     str = sprintf('[%d]',min(n));    lstr = [str,'-vector(s)'];
2300 else
2301     str=''; for i = 1:dn
2302         if isfinite(n(i)), str = sprintf('%s,%d',str,n(i));
2303         else, str = sprintf('%s,*',str); end
2304     end
2305     str = ['[',str(2:end),']'];    lstr = [str,'-matrix'];
2306 end
2307 if l, str=sprintf('\t%s',lstr); else, str=[str,' ']; end
2308 
2309 
2310 function [p,msg] = sf_SzChk(p,n,msg)
2311 %=======================================================================
2312 %-Size checking
2313 if nargin<3, msg=''; end
2314 if nargin<2, n=[]; end, if isempty(n), n=NaN; else, n=n(:)'; end
2315 if nargin<1, error('insufficient arguments'), end
2316 
2317 if isstr(p) | any(isnan(n(:))), return, end
2318 if length(n)==1, n=[n,1]; end
2319 
2320 dn = length(n);
2321 sp = size(p);
2322 dp = ndims(p);
2323 
2324 if dn==2 & min(n)==1
2325     %-[1,1], [1,n], [n,1], [1,Inf], [Inf,1] - vector - allow transpose
2326     %---------------------------------------------------------------
2327     i = min(find(n==max(n)));
2328     if n(i)==1 & max(sp)>1
2329         p='!'; msg='scalar required';
2330     elseif ndims(p)~=2 | ~any(sp==1) | ( isfinite(n(i)) & max(sp)~=n(i) )
2331         %-error: Not2D | not vector | not right length
2332         if isfinite(n(i)), str=sprintf('%d-',n(i)); else, str=''; end
2333         p='!'; msg=[str,'vector required'];
2334     elseif sp(i)==1 & n(i)~=1
2335         p=p'; msg=[msg,' (input transposed)'];
2336     end
2337 
2338 elseif dn==2 & sum(isinf(n))==1
2339     %-[n,Inf], [Inf,n] - n vector(s) required - allow transposing
2340     %---------------------------------------------------------------
2341     i = find(isfinite(n));
2342     if ndims(p)~=2 | ~any(sp==n(i))
2343         p='!'; msg=sprintf('%d-vector(s) required',min(n));
2344     elseif sp(i)~=n
2345         p=p'; msg=[msg,' (input transposed)'];
2346     end    
2347 
2348 else
2349     %-multi-dimensional matrix required - check dimensions
2350     %---------------------------------------------------------------
2351     if ndims(p)~=dn | ~all( size(p)==n | isinf(n) )
2352         p = '!'; msg='';
2353         for i = 1:dn
2354             if isfinite(n(i)), msg = sprintf('%s,%d',msg,n(i));
2355             else, msg = sprintf('%s,*',msg); end
2356         end
2357         msg = ['[',msg(2:end),']-matrix required'];
2358     end
2359 
2360 end

Generated on Wed 29-Apr-2009 01:06:38 by m2html © 2005