# The edit pseudo object

The slider control is Matlab's most versatile way to control a numeric parameter because it allows us to change a value continuously and repeatedly using several different methods (click & hold on an arrow, click & hold in the trough, and drag the slider bar). The pseudo slider object (described later in this table) enhances this capability further by providing more movement options and coupling it with the labels and numeric readout normally needed with the slider. The only downside to the pseudo slider is that it takes up too much space to use it everywhere in a GUI containing many numeric controls. For this reason an edit box (i.e. uicontrol('Style','Edit')) is often used to control a numeric parameter. However, because the only way to change the value of an edit box is to type in a new number, it is difficult to use when many adjustments are needed to arrive at an optimal setting or when you want to develop a feel for the effect of small changes in the parameter. The edit pseudo object was designed primarily to overcome that difficulty, although it also has the following additional advantages over the uicontrol edit box:

- A label is almost always required for a numeric parameter and is sometimes needed for string parameters as well. The uicontrol edit box doesn't have this label so you must add another uicontrol for that purpose, complicating your program and making it more difficult to reposition. The edit pseudo object includes an optional label so when you move the edit object its label automatically moves along with it.
- The edit pseudo object may be positioned using figure coordinates or using the normalized or data coordinates of an axis. Which coordinates to use is usually obvious and depends on the use of the particular control. (The uicontrol edit box may only use figure coordinates.)
- The edit pseudo object takes up even less space in your GUI than an uicontrol edit box so you can fit more controls into a given area. This often simplifies your GUI design by avoiding the need for additional modes to control which parameters are in view.
- The edit pseudo object has the (optional) ability to honor set minimum and maximum values.
- The string substitutions of the edit pseudo object's callback function often greatly simplify the callback routines.

There are two types of edit pseudo objects:

- Type 1: Two uicontrol objects are created (text style) inside the current figure.
  (If a label is not specified, only a single uicontrol is created.)
  This type is created if the 'pos' property has length 4 ([x y width height]).
- Type 2: Two text objects are created inside the current axis.
  (If a label is not specified, only a single text object is created.)
  This type is created if the 'pos' property value has length 2 ([x y]).

For reference, this first table describes the edit pseudo object properties that you may set and query. How to use these properties will become clear later when the commands are discussed:

Property Name | Property Value
value |
v (scalar) | Sets the edit object's numerical value to v. (default = 1)
[min max] (length 2 vector) | Sets the edit object's allowed min/max values (default = [-1e99, 1e99])
[v min max] (length 3 vector) | Sets both of the above.
Except for the length 2 argument case, the callback function is called if it has been provided earlier in the argument list or in a previous call to plt('edit').
val | Equivalent to the value property above, except that the callback is never called.
minmax | Equivalent to the val property above. (For clarity, use this only when the argument has length 2 (i.e. [min max]).
callbk | A callback to be executed when the edit text object is changed. If the callback is defined with a string, then: Occurrences of '@VAL' will be replaced with the current value. Occurrences of '@OBJ' will be replaced with the edit text handle. Also, note that if the function is defined as a string argument often consecutive single-quote characters are required (quotes within quotes). In that case, readability can be improved by replacing all sequences of two consecutive single quotes with a double quote character. For example 'disp(''ABC'');' could be written as 'disp("ABC");'. Note that this trick does not work for Matlab callbacks in general, but it does work for any callback defined within a plt(...) function call.
enable | -1=invisible, 0=disabled, 1=enabled (default=1). If disabled, the text will still be visible, but may not be modified.
incr | The increment value for a numeric edit pseudo object. (default = 1) When you click on the right/left side of the center of the object, the value of the pseudo edit object is increased/decreased by "incr". A negative value of "incr" is used to indicate that the increment factor is in percentage terms instead of absolute. For example, if incr = -0.1 then clicking on the right/left side of the edit object will increase/decrease the edit object's value by 0.1 percent (i.e. from 1000 to 1001 or 999). You can disable the increment/decrement feature in two different ways. The first way is to set the incr parameter to zero. When you do that, left or right clicking on the object will have the same effect (i.e. the edit mode is entering allowing you type in a new value). The second way is to set the incr parameter to inf. In that case you only enter edit mode when you right click on the object (just like when incr=1 or any nonzero number). Left clicking the object will call the callback function but has no other effect. This makes the object behave much like a button except that you can edit the button's value or string. (See below for an example of creating an editable button.)
length | The length of the vector allowed as the edit value. Usually, length=1 indicating the edit value must be a scalar. If length=4 (for example), an allowed edit value must be a row or column vector of length 4. Two special cases are length=-1 and length=0. length=-1 is used to indicate that a numeric array of any length is a legal value. length=0 is used for string edit objects i.e. the edit string is not interpreted as a number or vector. (default = 1)
format | The number of characters used to display numeric edit objects (default=6). Or you may specify the conversion string to use, such as '%0.4g' or '%3d' or '%4V' (Type "help prin" for a description of the allowed formatting codes.) Note that 'format',5 is equivalent to 'format','%5w'
label | If the argument is a string, that string will become the edit pseudo object's label. Usually, this is sufficient, but if you want more control of the label's position or appearance the argument may be a cell array of the form: {'LabelString', offset, 'Property1',Value1,'Property2',Value2, ...} Note that the label will be created with the same type as the main edit object (i.e. a uicontrol for type 1 and a text object for type 2). The property names in the cell array must be valid properties for that object type. Note that the label will be created as a text object in the same axis that is used to display the popup choices. Property1, Property2, etc. must all be valid text object property names. The meaning of the offset parameter depends on its length as follows:
Offset | Meaning for Type 1 | Meaning for Type 2
'' or [] | plt estimates the best label size & position based on the # of characters in the label. | Same as for type 1.
q | The label width is set to q. plt estimates the best label height & position. | The label position is set to: edit object position + [real(q) imag(q)]
[q1 q2] | The label width is set to q1. The label position is set to: edit object position + [real(q2) imag(q2)] | The label position is set to [q1 q2 0]
[q1 q2 q3] | NA | The label position is set to [q1 q2 q3]
[q1 q2 q3 q4] | The label position/size is set to [q1 q2 q3 q4] | NA
For a type 1 edit object, if the estimated width of the label based on its character length is too big or too small you may adjust it using the "q" parameter as described above. However an alternate method is to use the label itself. You can make the width bigger by padding the label with blanks. You can also make the width smaller by using the tilde character. For example if the desired label is "Abcdef", you can make it slightly smaller by specifying the label as "Abcde~f" or smaller still by using "Abcd~ef", or "Abc~def" etc. (Note the tilde character itself does not appear in the label.)
***** | If a property name is given which isn't in the list above then the property is applied to the main uicontrol or text object itself. (It must be a valid property name for type of object being used.) The position ('pos') of the edit pseudo object must be set this way. For a type 1 edit pseudo object the foreground/background colors ('foregr' / 'backgr' properties) are usually set this way, however, if these properties are not specified the background color defaults to 0.8 times the figure background color and foreground color defaults to [1 1 .4] or [0 0 .6] (whichever provides the most contrast). The text color of a type 2 edit pseudo object can be set this way as well ('color' property) with its default handled in the same manner as the foreground color for the type 1 object.

The following commands are used to create an edit pseudo object:

H = plt('edit', 'Property1',Value1, 'Property2',Value2,...) | The property names allowed and the interpretation of the property values are shown in the table above. You may use as many or as few properties as you need in whatever order you choose. If you favor clarity over conciseness, there is no need to consider the alternate forms shown below.
H = plt('edit',[x y],v, 'Property3',Value3,...) | Usually both the 'position' and 'value' properties are needed, so for conciseness, you may omit those property names if the property values appear first and in this order. Note that v in this form may also be a length 3 vector if you want to specify the min/max values. The position in this example is for a type 2 edit pseudo object but it could also be a 4 element vector [x y width height] specifying a type 1 edit object. Assuming at least one of the position coordinates is greater than 3 (indicating pixel units are being used), this command is translated into this line before execution: H = plt('edit','units','pixel','pos',[x y],'val',v,'Property3',Value3,...) If all position coordinates are less than 3 indicating that normal coordinates are being used, the translation is the same except 'pixel' is replaced with 'normal'.
H = plt('edit',[x y],v,@cb, 'Property4',Value4,...) | This command is equivalent to: H = plt('edit',[x y],v,'callbk',@cb,'Property4',Value4,...) Since most pseudo edit objects will be created with a callback, the 'callbk' property name can also be omitted by specifying the callback immediately after the position and value arguments. In this example the callback is specified by a function handle (@cb) but it may also be specified as a string. Property names other than these three ('pos', 'val', 'callbk') may not be omitted.

The above calls create an edit pseudo object and return the handle of the main uicontrol (for type 1) or main text object (for type 2) created. (By "main" I mean the object containing the value, not the label). This handle (H) may be used to modify or query the edit pseudo object parameters using the forms below:

plt('edit',H, 'Property1',Value1, 'Property2',Value2,...) | The specified property values are applied to the edit pseudo object identified by handle H. The property names can be the ones described in the table above as well as standard Matlab property names to be applied to the main uicontrol (for type 1) or text object (for type 2).
plt('edit',H,'get','value') | returns the numeric value of the specified edit pseudo object. For conciseness, this command may also be written without the last argument: plt('edit',H,'get') or even without the last two arguments: plt('edit',H)
plt('edit',H,'get','minmax') | returns [min max] - the allowed limits for the value
plt('edit',H,'get','callbk') | returns the string or function handle that was set via the 'callbk' parameter
plt('edit',H,'get','enable') | returns -1/0/1 if the pseudo object is hidden/disabled/enabled
plt('edit',H,'get','incr') | returns the value that was set via the 'incr' parameter
plt('edit',H,'get','length') | returns the value that was set via the 'length' parameter
plt('edit',H,'get','format') | returns the string that was set via the 'format' parameter
plt('edit',H,'get','label') | returns the label handle
plt('edit',H,'get','cell') | returns an 9 element cell array that is a concatenation of the previous 8 get commands: {val min max callback enable incr length format label}. The word 'cell' may be replaced by any string other than one of the other 8 valid 'get' arguments.
| The 9 'get' commands above also work when H is a vector of pseudo edit handles. For example, suppose H is a row or column vector containing 4 pseudo edit handles. Then the command plt('edit',H,'get','value') (the last two arguments are optional) will return a length 4 column vector of values from the 4 edit objects. Another example is the command plt('edit',H,'get','cell') which would return a 4 by 9 cell array where the nth row contains the 9 values from the nth pseudo object. There are two limitations to the get command with a vector of objects. The first is that 'get','callbk' only works if the callbacks are defined as strings of the same length. If the callbacks are function handles or strings of different lengths, the workaround is to use the 'get','cell' and save the fourth column of the result. The second limitation is that 'get','format' only works if the formats are strings of the same length. If they are strings of different lengths you can again use the 'get','cell' command and retrieve the formats from 8th column of the result.

Editable button:
As mentioned above in the description of the 'incr' parameter, it is possible to use the edit pseudo object to create an editable button. This could be used with a numeric value (as demonstrated by the "num quant" and "den quant" objects in the editz demo program) although perhaps more often it will be used with a string. (The 'length' parameter is set to zero to indicate the edit object is a string.) Here are two examples of string editable buttons, the first being a type 1 pseudo edit object and the second being a type 2:
plt('edit',[x y width height],0,@cb,'incr',inf,'length',0,'str','ABCD','Backgr',[0 0 1]);
plt('edit',[x y], 0,@cb,'incr',inf,'length',0,'str','ABCD','border',[0 0 1]);
Both of these will create a button containing the text "ABCD", the first one at the specified figure window coordinates with a solid blue background and the 2nd one at the specified axis coordinates with a blue border. (The border is not required but helps give the impression that the object acts like a button.) Left clicking on the button will call the @cb callback function. Right clicking on the button allows you to edit the button string. (The @cb function is also called after the string has been edited.)
Keyboard and mouse behavior:
Right-clicking on the edit text object always "opens" the object for editing. What this means is that the old edit string appears with the cursor (underscore) at the end of the string indicating that it is ready to accept keys typed at the keyboard. If you start typing right away, the new characters typed will be appended to the end of the old string. To insert the new characters at a point other than the end, simply move the cursor to the desired point using the left/right arrow keys. To remove characters, press <Backspace> or <Delete> to remove a character before or after the cursor. Pressing <Delete> when the cursor is at the end of the string deletes all the characters. This special case makes it easier to enter a new string that bears little resemblance to the previous entry. Note that while typing, the text object is shown in a different color to remind you that a new value is being entered. When you press <Enter>, the new string is accepted and the color returns to the original. If you type an invalid entry, the word "error" will appear. Click again on the "error" string to try the entry again or to recover the previous entry (via <Esc>). A summary of the special keys follows:

<Esc> | The edit text object is closed for editing and the original text value is restored as if the edit object was never opened for editing.
<Backspace> | Deletes the character on the left side of the cursor.
<Delete> | Deletes the character on the right side of the cursor. If the cursor is at the end of the string, all the characters are deleted leaving only the underscore cursor.
<Right arrow> | Moves the underscore cursor one position to the right.
<Left arrow> | Moves the underscore cursor one position to the left.
<Down arrow> | Removes all the characters. This is the same as pressing Backspace until only the underscore remains.
<Enter> | Closes the edit text object, accepting the current entry (without the underscore cursor) as the new value.
<Click> | Clicking the mouse on the edit text object while it is open has the same effect as pressing <Esc> on the keyboard.
i | When entering a scalar value, if lower case "i" (increment) is entered as the last character, this indicates that the entered value should be used as a new "incr" parameter for the object. In this case, the text object value from before the object was opened is retained.

Left-clicking on the edit text object also opens the object for editing except for one important exception. This exception happens when the edit text object is a scalar (i.e. the length parameter is equal to one). In fact this is more the rule than the exception since that is the most commonly used (and default) value for the length parameter.
In this (scalar parameter) case, when you left-click on the edit text object, its value is incremented or decremented by the object's "incr" parameter. Whether the value is incremented or decremented depends on the position of the mouse click. If you click to the right of the edit object's center, the value will be incremented. Likewise, the value will be decremented for clicks to the left of center. As an example, suppose the current edit text object has a value of 259, and the increment parameter is 1. Left-clicking on the 9 will change the edit object's value to 260 (because the 9 is right of the center of the text string). On the other hand, left-clicking on the two will decrement the value by one. Remember that if the increment amount is not convenient, you can change the increment amount on the fly by using the "i" character as described above.
An important property of the scalar increment/decrement feature is that the edit object will continue to increment as long as you hold down the mouse button. This is useful for many interactive controls and allows the edit objects to take the place of sliders (the only other handle graphic object to have this repeat property). When you hold down the mouse button, there will be a delay of 0.4 seconds before the auto-incrementing begins. After that delay, the value will be incremented once every 0.03 seconds. You can alter the repeat rate by setting the pseudo object's application data repeat property. For example, if you want a slower repeat rate (half the speed of the default) use the command:
setappdata(H,'repeat',0.06);
where H is the handle of the pseudo edit object. You can change the default repeat delay as well. For example, the command setappdata(H,'repeat',[0.06 0.25]); changes the repeat rate to 0.06 seconds and the repeat delay to 0.25 seconds. You can also inhibit the repeat feature by setting the repeat delay to a negative number, for example: setappdata(H,'repeat',-1);.
The easiest way to reset back to the default repeat and repeat delay values is to set the 'repeat' property to null ([] or '') or simply remove this property altogether, i.e. rmappdata(H,'repeat').
Whenever a number is being typed in, you may also type an expression instead. For example, the following entries are all equivalent:

- 5
- abs(3+4i)
- [2 1] * [2 1]'
- sqrt(3*2^3-cos(pi))

Typing sum(get(gca,'xlim').*[0 1])'would be equivalent to typing in the current upper x axis limit. And to be perverse, typing log(-1)/(2*pi) would be equivalent to typing ".5i" which as mentioned above would change the auto-increment value to one-half.
Creating multiple pseudo edit objects with one command
When using one of the forms of the plt edit command where the first argument specifies the position of the object, a single object will be created if that argument is a position vector. However, instead, that argument may be a cell array of position vectors. In that case, n pseudo edit objects will be created where n is the length of the cell array. If any of the remaining arguments are also a cell array of length n, then the kth cell array element will be applied to the kth pseudo edit object. For example the command:
H = plt('edit',{p1 p2 p3},In2,{In3A In3B In3C},In4,In5);
would have the same effect as the following 3 commands:

    H = [plt('edit',p1,In2,In3A,In4,In5);
         plt('edit',p2,In2,In3B,In4,In5);
         plt('edit',p3,In2,In3C,In4,In5)];

In this example, In3 was a cell array while In2, In4, and In5 were not, but it could just as easily be the other way around, or any other combination. Although this example included 5 arguments, it can have more, and only the first two arguments (the position and value) are required.
Querying or modifying multiple pseudo edit objects with one command
All the commands listed above where the first argument (after the 'edit') is a handle will also accept a vector or cell array of handles. The rules for the remaining arguments (if any) after the vector of handles are the same as above, i.e. if the argument is a cell array whose length is the same as the handle vector, then the nth element of that cell array is applied to nth handle. Otherwise the entire argument is applied unchanged to all the handles. To experiment with dealing with multiple objects we can use the arrange utility to create multiple objects without the drudgery of typing in several position coordinates. For example, try typing these commands into the command window:

        % create 4 pseudo edit objects with values 77,66,55,44
        h = plt('edit',arrange(4),{77 66 55 44},'label',{'first' 'second' 'third' 'fourth'});
        plt('edit',h)                            % verify that it worked by displaying the 4 values
        plt('edit',h,'val',num2cell(rand(1,4))); % change the 4 values to random numbers
        plt('edit',h)                            % verify that it worked by displaying the 4 values
        g = plt('edit',h,'get','label')          % get the handles of the labels for each pseudo edit object
        set(g,'foregr','black');                 % change the labels so that the text color is black
        set([h; g],'vis','off');                 % make the edit objects including the labels invisible
        set([h; g],'vis','on');                  % make them visible again

See the following programs for examples of the use of the pseudo edit object:

math folder: | airspeed, circles12, curves, gpsLog, julia
sig folder: | afilt, editz, erip, psdZoom, winplt