Generalized Input

The fundamental paradigm of most computer languages, including the Wolfram Language, is that input is given and processed into output. Historically, such input has consisted of strings of letters and numbers obeying a certain syntax.

Evaluate this input line to generate a table of output:

Table[n!,{n,1,10}]

Starting in Version 3, the Wolfram Language has supported the use of two-dimensional typeset mathematical notations as input, freely mixed with textual input.

This also generates a table of output:

Table[((n+3)/(n!)),{n,1,10}]

Starting with Version 6, a wide range of non-textual objects can be used as input just as easily, and can be mixed with text or typeset notations.

Evaluate the following input, then move the slider and evaluate it again to see a new result:

Table[((n+)/(n!)),{n,1,10}]

The "value" of this slider when it is given as input is determined by its position, in this case an integer between 1 and 10. It can be used anywhere in an input line that a textual number or variable name could be used.

How to create such controls is discussed in the next section, but it is worth noting first that in many cases there are better alternatives to this kind of input.

Casting this example in the form of a (RefLink[Manipulate, paclet:ref/Manipulate]) allows you to see the effect of moving the slider in real time:

Manipulate[Table[((n+m)/(n!)),{n,1,10}],{m,1,10,1}]

But there are situations where using a control inside a traditional Shift+MacOSXReturnEnter evaluated input works better. Some cases are: if the evaluation is very slow, if you want complete flexibility in editing the rest of the input line around the control(s), or if the point of the code is to make definitions that will be used later, and the controls are being used as a convenient way to specify initial values.

For example, you might want to set up a color palette using (RefLink[ColorSetter, paclet:ref/ColorSetter]) to initialize named colors that will be used in subsequent code:

edgeColor=Swatch;

fillColor=Swatch;

backgroundColor=Blend[{Swatch,Swatch}];

Click any color swatch to get a dialog allowing you to interactively choose a new color. These values can then be used in subsequent programming just as if they had been initialized with more traditional textually specified values:

Graphics[{
fillColor,EdgeForm[{AbsoluteThickness[2],edgeColor}],Polygon[RandomReal[{0,1},{5,3,2}]]},Background->backgroundColor]

These color swatches provide an informative, more easily edited representation of the colors than would an expression consisting of numerical color values.

How to Create Inline Controls

The most flexible and powerful way to create anything in the Wolfram Language is to evaluate a function that returns it.

These examples use (RefLink[Slider, paclet:ref/Slider]), but the same principles apply to any controls. Control Objects lists all the available control objects.

You can create a slider by evaluating (RefLink[Slider, paclet:ref/Slider])[]:

Slider[]

The resulting slider object can be copied and pasted into a subsequent input cell just as if it were any other kind of input. (Or you can just click in the output cell and start typing, which will cause it to be converted automatically into an input cell.)

Controls created this way are inert to evaluation.

For example, type 2+, then paste the previous slider after the + to create this input line, and then evaluate it:

2+

When evaluated, the slider remains a slider, which is not wanted in this case (though it is very useful in other situations). What is needed instead is a slider that, when evaluated as input, becomes the value it is set to, rather than a slider object.

Object that evaluates into its current setting.

When (RefLink[DynamicSetting, paclet:ref/DynamicSetting]) is wrapped around a slider and evaluated, the new slider looks identical to the original one, but has the hidden property of evaluating into its current setting.

This displays the new slider:

DynamicSetting[Slider[]]

If the new slider is copied and pasted into an input line, the act of evaluation transforms the slider into its current value (by default 0.5 if it has not been moved with the mouse):

2+

The examples in the previous section were created using (RefLink[DynamicSetting, paclet:ref/DynamicSetting]) in this way.

While copying and pasting can be used very effectively to build up input lines containing controls, it is often most convenient to use (MenuGrayLink[Evaluate in Place, paclet:ref/menuitem/EvaluateInPlace]) Ctrl+Shift+Enter (Command+Return on Mac) to transform control expressions in place, especially once you are familiar with the commands that create controls.

Evaluating in place.

For example, enter the following input line:

2+DynamicSetting[Slider[]]

Then, highlight the entire control expression. (Triple-clicking the word (RefLink[DynamicSetting, paclet:ref/DynamicSetting]) is an especially quick way to do this.)

2+DynamicSetting[Slider[]]

Type Ctrl+Shift+Enter (Command+Return on Mac), and the control expression will be transformed in place into an actual control. (Note that Ctrl+Shift+Enter is not the normal Shift+Enter used for evaluating input.)

2+

Evaluating the input cell with Shift+MacOSXReturnEnter will then give the desired result:

2+

All the arguments of (RefLink[Slider, paclet:ref/Slider]) can be used to change the initial value, range, and step size.

Start with this input expression:

Expand[(((1+x))^(DynamicSetting[Slider[5,{1,50,1}]]))]

Then evaluate in place (Ctrl+Shift+Enter) to transform the text command into a slider:

Expand[(1+x)]

Of course, this works with other kinds of controls as well:

Expand[(((1+x))^(DynamicSetting[PopupMenu[5,Table[i,{i,50}]]]))]

This is the result after evaluating in place:

Expand[(1+x)]

Note that the control expressions do not contain a dynamic reference to a variable as they normally would (see "Introduction to Dynamic"). Controls used in input expressions as described here are static, inert objects, much like a textual command. They are not linked to each other, and nothing happens when you move one, except that it moves. Basically they are simply recording their current state, for use when you evaluate the input line.

Complex Templates in Input Expressions

It is possible to use whole panels containing multiple controls in input expressions. Constructing such panels is more complex than simply wrapping (RefLink[DynamicSetting, paclet:ref/DynamicSetting]) around a single control, because you have to specify how the various control values should be assembled into the value returned when the template is evaluated.

The function (RefLink[Interpretation, paclet:ref/Interpretation]) is used to assemble a self-contained input template object, which may contain many internal parts that interact with each other through dynamic variables. The arguments are (RefLink[Interpretation, paclet:ref/Interpretation])[variables,body,returnvalue].

The first argument gives a list of local variables with optional initializers in the same format as (RefLink[Module, paclet:ref/Module]) or (RefLink[DynamicModule, paclet:ref/DynamicModule]). (In fact, (RefLink[Interpretation, paclet:ref/Interpretation]) creates a (RefLink[DynamicModule, paclet:ref/DynamicModule]) in the output. See "Introduction to Dynamic".)

The second argument is typeset to become the displayed form of the interpretation object. Typically it contains formatting constructs and controls with dynamic references to the variables defined in the first argument.

The third argument is the expression that will be used as the value of the interpretation object when it is given as input. Typically this is an expression involving the variables listed in the first argument.

Object that displays as one expression and evaluates as another.

Evaluating the following input cell creates an output cell containing a template for the (RefLink[Plot, paclet:ref/Plot]) command:

Interpretation[{f=Sin[x],min=0,max=2Pi},
Panel[Grid[{
{Style["Plot",Bold],SpanFromLeft},
{"Function:",InputField[Dynamic[f]]},
{"Min:",InputField[Dynamic[min]]},{"Max:",InputField[Dynamic[max]]}}]],
Plot[f,{x,min,max}]]

This template can be copied and pasted into an input cell, and the values edited as you like. Shift+MacOSXReturnEnter evaluation of the input cell generates a plot:

In the following more sophisticated example, the variable definite is used to communicate between the controls in the template, dimming the min and max value fields when indefinite integration is selected:

Interpretation[{f=(x^2),var=x,definite=False,min=a,max=b},Panel[Grid[{
{Style["Integrate",Bold],SpanFromLeft},
{"Function:",InputField[Dynamic[f],FieldSize->{{20,Infinity},{1,Infinity}}]},
{"Variable:",InputField[Dynamic[var]]},
{Row[{Checkbox[Dynamic[definite]],"Definite integral"}],SpanFromLeft},
{"Min:",InputField[Dynamic[min],Enabled->Dynamic[definite]]},{"Max:",InputField[Dynamic[max],Enabled->Dynamic[definite]]}}]],If[definite,Integrate[f,{var,min,max}],Integrate[f,var]]]

This copy of the previous template gives the integral upon evaluation:

As with the single controls in earlier sections, these input templates can be copied and pasted into new input cells, and they can be freely intermixed with textual input.

To test the result of integration, wrap the template with (RefLink[D, paclet:ref/D]) to take the derivative and verify that the result is the same as the starting point:

D[,x]

These examples are fairly generic: they look like dialog boxes in a lot of programs. But there are some important differences. For example, note the (x^2) in the input field. Input fields in the Wolfram System may look like those in other programs, but the contents can be any arbitrary typeset mathematics, or even graphics or other controls. (See the next section to learn how to write templates that can be nested inside each other.)

Wolfram System templates (and dialog boxes) are also not restricted to using a regular grid of text fields.

Here is a simple definite integration template laid out typographically:

Interpretation[{f=(x^2),var=x,min=a,max=b},Panel[Row[{
Underoverscript[Style["∫",36],
InputField[Dynamic[min],FieldSize->Tiny],InputField[Dynamic[max],FieldSize->Tiny]],
InputField[Dynamic[f],FieldSize->{{10,Infinity},{1,Infinity}}]," \[DifferentialD] ",InputField[Dynamic[var],FieldSize->Tiny]}]],
Integrate[f,{var,min,max}]]

Note that you do not need a template to evaluate integrals; they can be entered as plain typeset math formulas using keyboard shortcuts (as described in "Entering Two-Dimensional Expressions") or the Basic Input palette:

(∫_a^b)(x^2)\[DifferentialD]x

Whether it is useful to make a template like this or not depends on many things, but the important point is that in the Wolfram System the full range of formatting constructs, including text, typeset math, and graphics, is available both inside and around input fields and templates.

Advanced Topic: Dealing with Premature Evaluation in Templates

Templates defined like those in the previous section do not work as you might hope if the variables given in initializers already have other values assigned to them (for example, if the variable x has a value in the previous section), or if template structures are pasted into the input fields. To deal with evaluation issues correctly, it is necessary to use (RefLink[InputField, paclet:ref/InputField]) objects that store their values in the form of unparsed box structures rather than expressions. (Box structures are like strings in the sense that they represent any possible displayable structure, whether it is a legal Wolfram Language input expression or not.)

This defines a template:

Interpretation[{
f=MakeBoxes[(x^2)],
var=MakeBoxes[x],
definite=False,
min=MakeBoxes[a],
max=MakeBoxes[b]},
Panel[Grid[{
{Style["Integrate",Bold],SpanFromLeft},
{"Function:",InputField[Dynamic[f],Boxes,FieldSize->{{20,Infinity},{1,Infinity}}]},
{"Variable:",InputField[Dynamic[var],Boxes]},
{Row[{Checkbox[Dynamic[definite]],"Definite integral"}],SpanFromLeft},
{"Min:",InputField[Dynamic[min],Boxes,Enabled->Dynamic[definite]]},{"Max:",InputField[Dynamic[max],Boxes,Enabled->Dynamic[definite]]}}]],With[{f=ToExpression[f],var=ToExpression[var],min=ToExpression[min],max=ToExpression[max]},If[definite,Integrate[f,{var,min,max}],Integrate[f,var]]]]

This copy of the previous template gives the integral upon evaluation:

This template will work properly even under what might be considered abuse. For example, you can nest it repeatedly to integrate a function several times:

Note how the (RefLink[InputField, paclet:ref/InputField]) grows automatically to accommodate larger contents. (This behavior is controlled by the (RefLink[FieldSize, paclet:ref/FieldSize]) option.)

The typographic template can also be made robust to evaluation:

Interpretation[{
f=MakeBoxes[(x^2)],
var=MakeBoxes[x],
definite=False,
min=MakeBoxes[a],
max=MakeBoxes[b]},Panel[Row[{
Underoverscript[Style["∫",36],
InputField[Dynamic[min],Boxes,FieldSize->Tiny],InputField[Dynamic[max],Boxes,FieldSize->Tiny]],
InputField[Dynamic[f],Boxes,FieldSize->{{10,Infinity},{1,Infinity}}]," \[DifferentialD] ",InputField[Dynamic[var],Boxes,FieldSize->Tiny]}]],
With[{f=ToExpression[f],var=ToExpression[var],min=ToExpression[min],max=ToExpression[max]},Integrate[f,{var,min,max}]]]

Graphics as Input

Graphic objects, including the output of (RefLink[Graphics, paclet:ref/Graphics]), (RefLink[Graphics3D, paclet:ref/Graphics3D]), plotting commands, and graphics imported from external image files, can all be used as input and freely mixed with textual input. There are no arbitrary limitations in the mixing of graphics, controls, typeset mathematics, and text.

Evaluate a simple plot command:

Plot[Sin[x],{x,0,2Pi}]

Then click to place the insertion point just to the left of the plot and type "Table[":

Table[

Complete the command by clicking and typing to the right of the plot, then evaluating:

Table[,{5}]

Notice how the plot appears in several different sizes depending on its context. There are three standard automatic plot sizes, the largest if the plot is by itself in an output, smaller if used in a list or table output, and smallest if in a textual input line. This is mainly a convenience to make graphical input less bulky. You are always free to resize the graphic by clicking it and using the resize handles, or by including an explicit (RefLink[ImageSize, paclet:ref/ImageSize]) option.

You can import a bitmap image from a file:

Import["ExampleData/peacock.tif"]

Then copy/paste this into an input cell to do simple image processing on it:

//ColorNegate

The ability to use graphics as input allows for remarkably rich input, as in this simple (RefLink[Manipulate, paclet:ref/Manipulate]) example:

Manipulate[
ImageApply[Mod[#+j,1]&,],{j,0,1,.01}]