Introduction to Control Objects

The Wolfram Language includes many controls and structures related to controls as part of its core language. These control objects are supported in a completely seamless way throughout the Wolfram Language, and can be used anywhere an expression can be used.

These control objects also have a rich option environment, through which their behavior and display can be varied to suit your particular needs. In many cases, the display can be completely taken over by the user, allowing interfaces to be built to arbitrary graphic design specifications.

The function (RefLink[Manipulate, paclet:ref/Manipulate]) is one such interface, which provides a simple and powerful environment for exploring Wolfram Language expressions. In fact, (RefLink[Manipulate, paclet:ref/Manipulate]) was actually written entirely in the Wolfram Language, using control objects and other layout constructs. For many applications, it is perfectly sufficient to just use (RefLink[Manipulate, paclet:ref/Manipulate]) rather than concerning yourself with the low-level control objects or with this tutorial. But if you have an application in mind that is not satisfied by an existing framework, there is no substitute for using the control objects directly.

Note that this tutorial will not discuss matters already covered in "Introduction to Dynamic", so it is suggested that you familiarize yourself with that tutorial first before proceeding with this one.

Buttons

Arguably the simplest control, the button control links a mouse click to a single action. The first argument to (RefLink[Button, paclet:ref/Button]) is the label that will be displayed on the button's face, and can be any Wolfram Language expression, including graphics or typeset objects. The second argument is the function that will evaluate when you click the button. The evaluation takes place in the kernel, and the output of this evaluation is typically not seen unless it produces some side effect.

Here is a simple button that increments a variable, along with a dynamic display of the value of that variable, so you can see the effect of clicking the button.

DynamicModule[{c=0},{Button["Increment c", c++], Dynamic[c]}]

Any evaluation that the Wolfram Language can do can be done by a button. And that evaluation happens when the button is clicked, not when the button is created. (See the documentation for the attribute (RefLink[HoldRest, paclet:ref/HoldRest]) for the technical details of how this is done.) But remember, the output of that evaluation is not shown as it is for Shift+MacOSXReturnEnter evaluation. So unless the button's function has a visible side effect, you may think the button is not doing anything, when in fact it is just not showing you that it is doing anything. Here are two buttons that perform identical actions, except that one of them makes the result visible in a new palette window, while the other merely does the requested evaluation silently.

{Button["Sin[x y]", Plot3D[Sin[x y],{x,0,3},{y,0,3}]],
Button["Sin[x y]", Plot3D[Sin[x y],{x,0,3},{y,0,3}]//CreatePalette]}

When building an interface, you may want to adjust details of the button's appearance. This is managed with the (RefLink[Appearance, paclet:ref/Appearance]) option to (RefLink[Button, paclet:ref/Button]). The Wolfram Language provides several built-in appearances for buttons, including "Palette" and "FramedPalette" for platform-standard palette buttons, and "DialogBox" for dialog box buttons, the default.

It is important to point out that the default Wolfram Language appearance of buttons and other controls is taken directly from the underlying operating system. So a control's appearance will be different on Windows than on Macintosh. For instance, dialog box buttons on Macintosh are designed to never be smaller than some minimum size.

There are other built-in appearances, as well as (RefLink[None, paclet:ref/None]), which draws no frame around your button. This can be useful if you want the button to have a completely custom appearance, which you would then specify yourself in the first argument for (RefLink[Button, paclet:ref/Button]).

Here is a very simple interface created from buttons that have (RefLink[Appearance, paclet:ref/Appearance])->(RefLink[None, paclet:ref/None]). Click one of the squares to change the color of the circle. Notice one problem with using buttons that have no recognizable frame is that users might not know that they are buttons at all. In this case, it is up to you to create an appearance that is obviously clickable.

DynamicModule[{color = Blue},
{Button[sq[Red], color = Red, Appearance -> None],
Button[sq[Blue], color = Blue, Appearance -> None],
Dynamic[Graphics[{color, Disk[]}]]},
Initialization:>(sq[c_] := Graphics[{c, Rectangle[]}, ImageSize -> 40]
)]

There are a few more options to (RefLink[Button, paclet:ref/Button]) that you may find especially useful. The (RefLink[Enabled, paclet:ref/Enabled]) option, for instance, indicates whether a button should accept mouse clicks or not. If (RefLink[Enabled, paclet:ref/Enabled]) is set to (RefLink[False, paclet:ref/False]), the button will be dimmed and will ignore mouse clicks.

(RefLink[Enabled, paclet:ref/Enabled]) is most often used in conjunction with (RefLink[Dynamic, paclet:ref/Dynamic]), so that the button accepts clicks as long as doing so makes sense, and then it stops. For example, if you look back at the increment button from above, you might want to impose a maximum value. Once that maximum value is attained, the setting for (RefLink[Enabled, paclet:ref/Enabled]) can automatically become (RefLink[False, paclet:ref/False]), and the button will then be dimmed. For completeness, add a decrement button too, which stops at a minimum value, and wrap the whole thing in a (RefLink[DynamicModule, paclet:ref/DynamicModule]) to isolate the variables.

DynamicModule[{c=0,min=0,max=10},
{Button["-", c--, Enabled->Dynamic[c>min]], Dynamic[c],Button["+", c++, Enabled->Dynamic[c<max]]}]

If you regularly use more than one kernel, or want to create buttons that use the front end directly, then you will want to know about the (RefLink[Evaluator, paclet:ref/Evaluator]) option. This can be set to the name of any kernel, or (RefLink[Automatic, paclet:ref/Automatic]) (the default) which means to use the current default kernel. The setting (RefLink[Evaluator, paclet:ref/Evaluator])->(RefLink[None, paclet:ref/None]) will cause actions to take place entirely within the front end if possible. See (RefLink[FrontEndExecute, paclet:ref/FrontEndExecute]) for details.

When using (RefLink[Button, paclet:ref/Button]) inside of (RefLink[Grid, paclet:ref/Grid]) or (RefLink[Column, paclet:ref/Column]), another option you should know about is (RefLink[ImageSize, paclet:ref/ImageSize]). By default, buttons will stretch in all directions to fill that element of the grid. This is due to the default setting of (RefLink[ImageSize, paclet:ref/ImageSize]), namely (RefLink[Full, paclet:ref/Full]). Here is a slight modification of the example above that shows that the buttons automatically resize when the (RefLink[Column, paclet:ref/Column]) they are in becomes wider.

DynamicModule[{c=8,min=0,max=10},
Column[{Button["-", c--, Enabled->Dynamic[c>min]], Dynamic[Range[c]],Button["+", c++, Enabled->Dynamic[c<max]]}]]

To override this behavior, use a different setting for (RefLink[ImageSize, paclet:ref/ImageSize]), such as (RefLink[Automatic, paclet:ref/Automatic]), which allows the buttons to remain their fixed, natural size. You can also use a fixed (RefLink[ImageSize, paclet:ref/ImageSize]) to specify the button's dimensions in printer's points.

DynamicModule[{c=8,min=0,max=10},
Column[{
Button["-", c--, Enabled->Dynamic[c>min], ImageSize->{50,50}],
Dynamic[Range[c]],
Button["+", c++, Enabled->Dynamic[c<max],ImageSize->{50,50}]}]]

The last of the options for (RefLink[Button, paclet:ref/Button]) you will look at is (RefLink[Method, paclet:ref/Method]). (RefLink[Method, paclet:ref/Method]) determines the way in which the button communicates with the kernel. With the default setting of "Preemptive", clicking the button will cause the evaluation to be sent to the kernel over the preemptive link. See "Advanced Dynamic Functionality" for details on the preemptive link. That is the same link used for dynamic evaluation. Such buttons will respond to user clicks immediately, even if the user is also running some long Shift+MacOSXReturnEnter evaluation on the main link.

Here is a simple example to illustrate the power of this setup. First, initialize a variable and display a preemptive button that changes the variable's value.

done=False;Button["done", done=True]

Next, use Shift+MacOSXReturnEnter to evaluate this (RefLink[While, paclet:ref/While]) command.

While[Not[done]]; "done"

Under normal circumstances, the only way out of this (RefLink[While, paclet:ref/While]) loop would be to abort the calculation. But since the button above is communicating with the kernel on a different link, it is not blocked by this (RefLink[While, paclet:ref/While]) loop. Clicking the button will initiate a preemptive evaluation that changes the value of the variable, which in turn causes the (RefLink[While, paclet:ref/While]) loop to end.

One important consequence of using (RefLink[Method, paclet:ref/Method])->"Preemptive" is that button evaluations are subject to the same timeout period as other dynamic evaluations, specified using the front end (RefLink[DynamicEvaluationTimeout, paclet:ref/DynamicEvaluationTimeout]) option. So if you have an evaluation that you expect will take more than a couple of seconds to evaluate, you should use (RefLink[Method, paclet:ref/Method])->"Queued". Clicking such a button will use the main link when evaluating its function, and that evaluation will be queued along with evaluations queued using Shift+MacOSXReturnEnter.

For instance, the buttons in the very large output suppression panel use (RefLink[Method, paclet:ref/Method])->"Queued", since handling very large outputs can require a considerable length of time.

Range[10^6]

The (RefLink[Button, paclet:ref/Button]) control is quite flexible and powerful, but there are a couple of common variations that warrant having their own, simple functions for generating them.

(RefLink[PasteButton, paclet:ref/PasteButton]) creates a button that performs a paste operation. (RefLink[Hyperlink, paclet:ref/Hyperlink]) creates a button that will jump to a given URI. (RefLink[FileNameSetter, paclet:ref/FileNameSetter]) creates a button that brings up a system file picker dialog, and then remembers the path to the chosen file. (RefLink[ColorSetter, paclet:ref/ColorSetter]) creates a button that will bring up a system color picker dialog.

(RefLink[ActionMenu, paclet:ref/ActionMenu]), which is discussed in the section "PopupMenu and ActionMenu", also performs a function similar to (RefLink[Button, paclet:ref/Button]). It allows the aggregation of multiple actions into a collection of menu items, each of which has an individual function that is executed exactly as the function of a (RefLink[Button, paclet:ref/Button]) is executed.

Other Controls

Most other controls have a somewhat different purpose, namely to associate themselves with a variable. The example of sliders, which will be discussed next, is shown in some detail in "Introduction to Dynamic". Almost all of the remaining controls detailed in this tutorial share this feature with sliders. Their main purpose is to display the current value of a variable, and to set the value of that variable when that control is used.

Such controls all have the same basic syntactic form:

where control is the name of the control, var is the variable the control will be changing, domainSpec is the optional specification for the space over which the control will work, and opts are options affecting how the control acts and looks.

Controls also all interact with the kernel over the preemptive link, and so are subject to the same timeout period as buttons with (RefLink[Method, paclet:ref/Method])->"Preemptive" as described in "Introduction to Control Objects", as well as other dynamic displays. This reinforces the notion that controls should only be used to control things that happen quickly. It makes no sense to have a slider initiate evaluations that may take minutes or hours to run. As with buttons though, there are ways to avoid this timeout, which will be looked at later on.

Sliders

There are a handful of sliders that are available in the Wolfram Language. The simplest one is a horizontal slider that allows you to choose any number between 0 and 1. Here, attach the slider to the variable x and add a dynamic display of this value so you can immediately see the slider's effect.

DynamicModule[{x},{Slider[Dynamic[x]], Dynamic[x]}]

Basic use of (RefLink[Slider, paclet:ref/Slider]) is covered rather thoroughly in "Introduction to Dynamic", but there are a couple of uses that are slightly uncommon. For instance, you can slow down your slider drags by holding down modifier keys. Details about this feature can be found in "Introduction to Manipulate".

You can also use a slider to choose among a set of discrete values instead of continuous values. Here are four sliders, each of which allows you to select certain items between 0 and 10. The first is a continuous slider that selects a real number; the second is an integer-valued slider; the third uses a rational step size to visit all multiples of 1/3; and the fourth slider demonstrates the ability of (RefLink[Slider, paclet:ref/Slider]) to range over a discrete set of specified objects, which might be integers, real numbers, or any other expression, in any order.

DynamicModule[{x},Column[{
Slider[Dynamic[x],{0,10}],
Slider[Dynamic[x],{0,10,1}],
Slider[Dynamic[x],{0,10,1/3}],
Slider[Dynamic[x],{{0,2,3,10,Panel["You have reached the end"]}}],
Dynamic[x]},Center]]//Panel

Notice that the position of a slider's thumb will always try to represent the value of the underlying variable. If the variable's value is not accessible on that slider, the thumb will move to one end of the slider and its background will turn a shade of red to indicate that the value is out of range.

Like (RefLink[Button, paclet:ref/Button]), (RefLink[Slider, paclet:ref/Slider]) has many options for changing its appearance and its use. The (RefLink[Appearance, paclet:ref/Appearance]) option determines, among other things, the size and shape of the slider thumb. Here are some of the built-in variations, some of which require the slider to change its orientation. (Note that the sliders are drawn by the operating system, and of course each operating system supports a slightly different set of appearances. If a slider appearance is not supported by your operating system, the default appearance will be used.)

Manipulate[Slider[Appearance -> appearance],{appearance,{"UpArrow","DownArrow","Vertical","LeftArrow","RightArrow"}}]

(RefLink[VerticalSlider, paclet:ref/VerticalSlider]) is also available, which automatically sets (RefLink[Appearance, paclet:ref/Appearance])->"Vertical".

(RefLink[Enabled, paclet:ref/Enabled]) and (RefLink[ImageSize, paclet:ref/ImageSize]) are not discussed again for (RefLink[Slider, paclet:ref/Slider]) or all other controls, but they work throughout in exactly the same way. The only difference is that (RefLink[ImageSize, paclet:ref/ImageSize])->(RefLink[Full, paclet:ref/Full]) is only supported by (RefLink[Button, paclet:ref/Button]), and not other controls. However, (RefLink[Slider, paclet:ref/Slider]) and the rest do support both symbolic and fixed numeric image sizes.

Manipulate[Slider[ImageSize -> size],{size,{Tiny,Small,Medium,Large,1000}}]

Notice that the appearance changes automatically for the different (RefLink[ImageSize, paclet:ref/ImageSize]) settings. That is because the default setting for the (RefLink[Appearance, paclet:ref/Appearance]) setting is (RefLink[Automatic, paclet:ref/Automatic]). If you want to combine an (RefLink[ImageSize, paclet:ref/ImageSize]) with a different (RefLink[Appearance, paclet:ref/Appearance]) for some reason, you can do that, too. Here, ask for components to draw at their medium size, while constraining the overall size to be tiny.

Slider[ImageSize -> Tiny, Appearance -> Medium]

Here is a good place to point out an interesting variation on (RefLink[Slider, paclet:ref/Slider]). The (RefLink[Manipulator, paclet:ref/Manipulator]) control has exactly the same syntax as (RefLink[Slider, paclet:ref/Slider]), but adds an input field and animation controls to its display. These are collapsed by default. Click the MagnificationFEBitmapsSquarePlusIconSmallMagnificationFEBitmapsSquarePlusIconMediumFEBitmapsSquarePlusIconLarge icon to expose them. (How to create input fields and animation controls separate from (RefLink[Manipulator, paclet:ref/Manipulator]) will be shown shortly.)

Manipulator[]

You can also reveal the animation controls automatically by specifying (RefLink[Appearance, paclet:ref/Appearance])->"Open".

Manipulator[Appearance -> "Open"]

(RefLink[Manipulator, paclet:ref/Manipulator]) supports a unique setting for (RefLink[Appearance, paclet:ref/Appearance]), "Labeled", which displays the usual constellation of controls along with a frameless input field outside the hidden area. Seeing and setting the value of the variable in this way can be quite convenient.

Manipulator[Appearance -> "Labeled"]

(RefLink[IntervalSlider, paclet:ref/IntervalSlider]) is a special kind of slider that allows the setting of two points on a range, typically thought of as an upper bound and a lower bound. The value of (RefLink[IntervalSlider, paclet:ref/IntervalSlider]) is a list of the two endpoints.

DynamicModule[{range},{IntervalSlider[Dynamic[range]],Dynamic[range]}]

This slider has three thumbs that can be manipulated. The upward pointing thumb on the left controls the lower value and the downward pointing thumb on the right controls the upper value. The space in between serves as a third thumb to move the entire interval.

Since there are two sliders, this raises some possibilities for what happens if you attempt to move the slider at one end of the interval past its opposite slider. The default behavior is to allow the user to do this, and represent it by flipping the order of the lower and upper bounds in the value.

IntervalSlider[{0.75,0.25}]

Another possibility is to prevent the ranges from being flipped entirely. This can be done using the (RefLink[Method, paclet:ref/Method]) option. (RefLink[Method, paclet:ref/Method])->"Stop" causes the left slider thumb to serve as an absolute stopping point for interactive manipulation of the right slider thumb and vice versa:

IntervalSlider[{0.4,0.6},Method->"Stop"]

(RefLink[Method, paclet:ref/Method])->"Push" allows the slider thumb in use to push the other one out of the way. For example, try dragging the right-hand slider thumb all the way to the left below.

IntervalSlider[{0.8,0.9},Method->"Push"]

Animator, Trigger, and ProgressIndicator

Animations are another important feature of the Wolfram Language, and (RefLink[Animator, paclet:ref/Animator]) is the name of the control used to manage them. The job of an (RefLink[Animator, paclet:ref/Animator]) control is to automatically push the value of a variable through a given domain. Here is an (RefLink[Animator, paclet:ref/Animator]) that runs the value of x from 0 to 1. When it gets to the top of the domain, it wraps around and starts again at the bottom.

DynamicModule[{x},{Animator[Dynamic[x],{0,1}], Dynamic[x]}]

As you can see, the (RefLink[Animator, paclet:ref/Animator]) control has several different elements in its display, known as (RefLink[AppearanceElements, paclet:ref/AppearanceElements]). There is the slider, which shows the current value of the variable (known as the "ProgressSlider"); the "-" and "+" buttons, which move the value a small amount to the left or right ("StepLeftButton" and "StepRightButton"); the button that toggles whether the (RefLink[Animator, paclet:ref/Animator]) is playing or paused ("PlayPauseButton"); and buttons to control the speed ("FasterSlowerButtons") and direction ("DirectionButton") of the animation. You can change the (RefLink[AppearanceElements, paclet:ref/AppearanceElements]) option to include only some of these, based on your current needs. Here is the same animation but with the (RefLink[Animator, paclet:ref/Animator]) displaying only a play button.

DynamicModule[{x},{Animator[Dynamic[x], {0,1},AppearanceElements -> "PlayPauseButton"], Dynamic[x]}]

In addition to showing controls for each of these aspects of an animation, (RefLink[Animator, paclet:ref/Animator]) provides options to set the initial state of these controls. (RefLink[AnimationRunning, paclet:ref/AnimationRunning]) lets you start up an animation in a paused state. (RefLink[AnimationDirection, paclet:ref/AnimationDirection]) lets you set the initial direction of an animation. (RefLink[DefaultDuration, paclet:ref/DefaultDuration]) and (RefLink[AnimationRate, paclet:ref/AnimationRate]) let you determine the speed of an animation (more about those in a minute).

(RefLink[Animator, paclet:ref/Animator]) supports all the same domains that (RefLink[Slider, paclet:ref/Slider]) does in its second argument, namely {min,max}, {min,max,step}, and {{(Subscript[a, 1]),(Subscript[a, 2]),(Subscript[a, 3]),…}}. In addition, (RefLink[Animator, paclet:ref/Animator]) also supports max being (RefLink[Infinity, paclet:ref/Infinity]) and min being -(RefLink[Infinity, paclet:ref/Infinity]).

DynamicModule[{x},{Animator[Dynamic[x],{0,Infinity}], Dynamic[x]}]

One important thing to keep in mind with animators is that, like other dynamics, they are only active while they are actually visible on the screen. If an (RefLink[Animator, paclet:ref/Animator]) is in a closed cell group, scrolled off-screen, or in some other hidden location, then it will not be actively changing the underlying variable. If you are using the online version of this document, opening the cell group below will cause the value of y to begin changing.

Animator[Dynamic[y]]

Dynamic[y]

Now back to duration. There are several ways to control how fast an animation runs. By default, an animation will run fast enough so that it gets from the start of its domain to the end in about five seconds. This time is determined by the (RefLink[DefaultDuration, paclet:ref/DefaultDuration]) option. Here are two animators that use this option, one of which runs twice as fast as the other.

DynamicModule[{x,y},Grid[{
{Animator[Dynamic[x],DefaultDuration -> 5],Dynamic[x]},
{Animator[Dynamic[y],DefaultDuration -> 10],Dynamic[y]}}]]

Instead of specifying the overall duration, you can specify how fast the animation runs in units per second via the optional third argument of (RefLink[Animator, paclet:ref/Animator]), which is a convenient argument for setting the (RefLink[AnimationRate, paclet:ref/AnimationRate]) option. This is especially useful for infinite animations, since setting the overall duration for an infinite animation would be meaningless.

DynamicModule[{x,y,z},Column[{
Animator[Dynamic[x],{0,1},0.2],
Animator[Dynamic[y],{0,1},1],
Animator[Dynamic[z],{0,Infinity,1},10],
Dynamic[{x,y,z}]}]]

Note that (RefLink[DefaultDuration, paclet:ref/DefaultDuration]) and (RefLink[AnimationRate, paclet:ref/AnimationRate]) are two ways to ultimately specify the same thing, namely how fast an animation is running. By default, (RefLink[AnimationRunning, paclet:ref/AnimationRunning]) is set to (RefLink[Automatic, paclet:ref/Automatic]), which indicates that the (RefLink[DefaultDuration, paclet:ref/DefaultDuration]) option should be respected. If (RefLink[AnimationRate, paclet:ref/AnimationRate]) is set to anything else (e.g. if you put a number in the third argument of (RefLink[Animator, paclet:ref/Animator])), then (RefLink[DefaultDuration, paclet:ref/DefaultDuration]) will be ignored.

Independent of (RefLink[DefaultDuration, paclet:ref/DefaultDuration]) and (RefLink[AnimationRate, paclet:ref/AnimationRate]), another thing you can specify is (RefLink[RefreshRate, paclet:ref/RefreshRate]), which specifies how many times per second the (RefLink[Animator, paclet:ref/Animator]) should change the value of the variable. By default, (RefLink[Animator, paclet:ref/Animator]) runs as fast as possible, which will constantly require CPU time. By setting a lower (RefLink[RefreshRate, paclet:ref/RefreshRate]), the kernel will have more time available to other evaluations. Here are three animators that use three different refresh rates. Every one of these animators still takes about five seconds to get from the minimum to the maximum, but those with the lower refresh rates will show fewer values over the course of the animation.

DynamicModule[{x,y,z},Column[{
Animator[Dynamic[x],RefreshRate -> 10],
Animator[Dynamic[y],RefreshRate -> 5],
Animator[Dynamic[z],RefreshRate -> 1],
Dynamic[{x,y,z}]}]]

The (RefLink[DisplayAllSteps, paclet:ref/DisplayAllSteps]) option also overrides (RefLink[DefaultDuration, paclet:ref/DefaultDuration]) and (RefLink[AnimationRate, paclet:ref/AnimationRate]) if necessary. When this is set to (RefLink[True, paclet:ref/True]), every element of a discrete domain is visited by the animation, regardless of whether it can do so in the time allowed.

DynamicModule[{x,y,z},Column[{
Animator[Dynamic[x],{0,1,0.1},DisplayAllSteps -> True],
Animator[Dynamic[y],{0,1,0.01},DisplayAllSteps -> True],
Animator[Dynamic[z],{0,1,0.001},DisplayAllSteps -> True],
Dynamic[{x,y,z}]}]]

When using (RefLink[Animator, paclet:ref/Animator]) to animate through a list of elements, there is a syntax for specifying relative frame durations for each individual frame. Instead of providing a list of frames {{(Subscript[a, 1]),(Subscript[a, 2]),(Subscript[a, 3]),…}}, replace each element (Subscript[a, i]) with the pair {(Subscript[a, i]),(Subscript[d, i])}, where (Subscript[d, i]) is the relative duration of the corresponding element.

{Animator[Dynamic[x],{Table[{i ,If[PrimeQ[i],10,1]},{i,1,100}]}, DefaultDuration->10], Dynamic[x]}

Lastly, (RefLink[AnimationRepetitions, paclet:ref/AnimationRepetitions]) is an option that indicates how many times to run through the animation before automatically stopping. The default is to cycle through the animation indefinitely, indicated by (RefLink[AnimationRepetitions, paclet:ref/AnimationRepetitions])->(RefLink[Infinity, paclet:ref/Infinity]), but it can be set to any finite value. Here is an (RefLink[Animator, paclet:ref/Animator]) that runs twice through and then stops.

Animator[0,{0,1},AnimationRepetitions->2]

In fact, (RefLink[Trigger, paclet:ref/Trigger]) is a variation of (RefLink[Animator, paclet:ref/Animator]) dedicated to pushing a variable through its domain once and then stopping. (RefLink[Trigger, paclet:ref/Trigger]) is intended for animations that should always be started from the beginning. Thus, (RefLink[Trigger, paclet:ref/Trigger]) has a pause button, but there is no unpause button. There is also a reset button, and of course the main trigger button.

DynamicModule[{x},{Trigger[Dynamic[x]], Dynamic[x]}]

Another control that is quite similar to (RefLink[Slider, paclet:ref/Slider]) and (RefLink[Animator, paclet:ref/Animator]) is (RefLink[ProgressIndicator, paclet:ref/ProgressIndicator]). As the name implies, (RefLink[ProgressIndicator, paclet:ref/ProgressIndicator]) will show a platform-standard progress indicator, drawn as a kind of thermometer on most platforms. Its syntax is identical to (RefLink[Animator, paclet:ref/Animator]) and (RefLink[Slider, paclet:ref/Slider]), and the value it displays is communicated via dynamic variables, just like other controls. Here, simulate a time-consuming evaluation with (RefLink[Pause, paclet:ref/Pause]), with an accompanying progress display.

ProgressIndicator[Dynamic[i],{1,100}]
Do[Pause[0.01],{i,100}]

For indeterminate computations where a thermometer is not appropriate, you can specify infinite limits to (RefLink[ProgressIndicator, paclet:ref/ProgressIndicator]), and it will display an indication that something is happening, without any indication of when it might finish.

ProgressIndicator[Dynamic[i],{1,∞}]
Do[Pause[0.01],{i,100}]

There is also a higher-level function, (RefLink[Monitor, paclet:ref/Monitor]), that can be used in cases like this. (RefLink[Monitor, paclet:ref/Monitor]) can display anything as the monitoring expression, but a (RefLink[ProgressIndicator, paclet:ref/ProgressIndicator]) is especially useful. Note that using (RefLink[Monitor, paclet:ref/Monitor]) also has the very nice feature that the monitoring expression is removed automatically when the evaluation of the first argument is finished.

Monitor[Do[Pause[0.01],{i,100}],ProgressIndicator[i,{1,100}]]

Slider2D and ColorSlider

These one-dimensional slider-like controls are useful, but what if you want to control something that is fundamentally a two-dimensional piece of data, like the coordinates of a point? For that purpose, you have (RefLink[Slider2D, paclet:ref/Slider2D]), which lets you move a slider thumb anywhere in a given area.

Slider2D[]

(RefLink[Slider2D, paclet:ref/Slider2D]) has the same basic syntax as (RefLink[Slider, paclet:ref/Slider]), except that the min and max are each allowed to be a pair of numbers instead of a single number. An optional step size can also be given.

DynamicModule[{x},
{Slider2D[Dynamic[x],{{0,-1},{10,1}}],
Slider2D[Dynamic[x],{{0,-1},{10,1},{1,1/7}}], Dynamic[x]}]

Like all controls, (RefLink[Slider2D, paclet:ref/Slider2D]) takes options like (RefLink[Enabled, paclet:ref/Enabled]) and (RefLink[ImageSize, paclet:ref/ImageSize]). (RefLink[ImageSize, paclet:ref/ImageSize]) is especially convenient here to change the aspect ratio of the slider to match the aspect ratio of the data.

DynamicModule[{x={0,0}},{
Slider2D[Dynamic[x],{{-5,-10},{5,10}}, ImageSize -> {100,200}], Graphics[Disk[Dynamic[x]],Frame->True,FrameTicks -> False,PlotRange -> {{-5,5},{-10,10}},ImageSize->{100,200}]}]

Another slider that moves through a two-dimensional space is (RefLink[ColorSlider, paclet:ref/ColorSlider]), which allows you to choose a color by clicking and dragging on a color gradient to the right. You can also open your system's color chooser dialog by clicking on the solid colored square at the left of the (RefLink[ColorSlider, paclet:ref/ColorSlider]).

DynamicModule[{c=Blue},
Column[{ColorSlider[Dynamic[c]], Dynamic[Graphics[{c, Disk[]}]]},Center]]

Checkbox and Other Toggling Controls

If you want a single control to cycle the value of a variable through two or more values, then you most likely will use (RefLink[Checkbox, paclet:ref/Checkbox]) or (RefLink[Toggler, paclet:ref/Toggler]). Here is a very simple example that shows how (RefLink[Checkbox, paclet:ref/Checkbox])[(RefLink[Dynamic, paclet:ref/Dynamic])[var]] toggles the value of the variable var between (RefLink[True, paclet:ref/True]) and (RefLink[False, paclet:ref/False]).

{Checkbox[Dynamic[a]],Dynamic[Plot[Sin[x],{x,0,10},Axes->a]]}

With its optional second argument, you can have checkbox cycle through not just (RefLink[True, paclet:ref/True]) and (RefLink[False, paclet:ref/False]), but any list of values. Using Shift+ Click will go to the previous value. Here you cycle through other possible settings for plot axes using (RefLink[Checkbox, paclet:ref/Checkbox]). A (RefLink[DynamicModule, paclet:ref/DynamicModule]) has been added to isolate this example from the previous one.

DynamicModule[{a},{
Row[{Checkbox[Dynamic[a],{False,True,{False,True},{True,False}}],"Axes"}],
Dynamic[Plot[Sin[x],{x,0,10},Axes->a]]}]

Despite being able to customize the values taken on by a checkbox, you cannot customize its display at all. (RefLink[Toggler, paclet:ref/Toggler]) is a generalization of (RefLink[Checkbox, paclet:ref/Checkbox]), which also lets you specify a completely custom display for your toggling control.

DynamicModule[{a},
{ Toggler[Dynamic[a],{False->"FF",True->"TT",{False,True}->"FT",{True,False}->"TF"}]//Framed,
Dynamic[Plot[Sin[x],{x,0,10},Axes->a]]}]

Finally, there are conveniences for constructing a set of checkboxes or togglers all at once. (RefLink[TogglerBar, paclet:ref/TogglerBar]) presents the controls arranged in an actual bar of buttons, while (RefLink[CheckboxBar, paclet:ref/CheckboxBar]) provides a set of labeled checkboxes. The value of the variable in these cases is taken to be the list of items that are currently checked, or toggled, in click order.

DynamicModule[{lis={}},Column[{
CheckboxBar[Dynamic[lis],Range[5]],
TogglerBar[Dynamic[lis],Range[5]],
Dynamic[lis]}]]

Of course, once you start specifying a set of controls with a set of labels, several questions arise about exactly how they are laid out. You can set (RefLink[Appearance, paclet:ref/Appearance]) to "Horizontal", "Vertical", or "Row" for (RefLink[CheckboxBar, paclet:ref/CheckboxBar]) and (RefLink[TogglerBar, paclet:ref/TogglerBar]), to get different layout and word-wrapping behaviors.

DynamicModule[{lis={}},Row[{
CheckboxBar[Dynamic[lis],Range[5],Appearance -> "Vertical"],
TogglerBar[Dynamic[lis],Range[5],Appearance -> "Vertical"],
Dynamic[lis]}]]

The (RefLink[Opener, paclet:ref/Opener]) control is another variant of (RefLink[Checkbox, paclet:ref/Checkbox]), which instead of displaying a box with or without a checkbox, displays a disclosure triangle that points right or down. The value assigned to the variable is a Boolean, just like (RefLink[Checkbox, paclet:ref/Checkbox]).

{Opener[Dynamic[x]],Dynamic[x]}

This academic example does not make much visual sense however, since the display of the (RefLink[Opener, paclet:ref/Opener]) control leads you to believe something should be appearing under it. The primary use of (RefLink[Opener, paclet:ref/Opener]) is actually in (RefLink[OpenerView, paclet:ref/OpenerView]), which provides this vertical layout automatically by internally using (RefLink[Opener, paclet:ref/Opener]) together with (RefLink[PaneSelector, paclet:ref/PaneSelector]) and (RefLink[Grid, paclet:ref/Grid]).

OpenerView[{"Title","Contents"}]

For details on (RefLink[OpenerView, paclet:ref/OpenerView]) and other view objects, please see "Views".

Column[OpenerView[{#, Plot[#[x],{x,0,10}]}]& /@ {Sin,Cos,Tan}]

RadioButton and Other Setting Controls

Another useful interface construct is the radio button, which allows users to choose exactly one element out of a set. (RefLink[RadioButton, paclet:ref/RadioButton]) is the Wolfram Language function that creates a radio button. Here is a radio button which, when selected, will set x equal to 1.

DynamicModule[{x},RadioButton[Dynamic[x],1]]

Of course, one radio button by itself is not very useful. Once you click it there is no way to unclick it, and clicking it again will have no effect. Connecting two or more radio buttons to the same variable will have the usual, choose-one-from-many effect that distinguishes radio buttons as interface elements.

DynamicModule[{x},{RadioButton[Dynamic[x],1],RadioButton[Dynamic[x],2], Dynamic[x]}]

Now, a set of radio buttons is not much good without labels. By the time you specify all radio buttons based on the same variable, and all the labels, there is quite a lot of redundancy. The Wolfram Language provides a function, (RefLink[RadioButtonBar, paclet:ref/RadioButtonBar]), that will create a set of radio buttons all tied to the same variable. You can specify labels for each radio button, with the default labels being the values themselves.

DynamicModule[{x},{RadioButtonBar[Dynamic[x],{1,2->"two"}], Dynamic[x]}]

For more complicated interfaces, it is sometimes useful to have the choose-one-from-many behavior of a radio button, but with the flexibility of providing a completely custom display. For that purpose, you have the (RefLink[Setter, paclet:ref/Setter]) construct. By default, a setter just looks like a button that appears either pressed or not in the same situations as a radio button would appear selected or not.

DynamicModule[{x},{Setter[Dynamic[x],1], Setter[Dynamic[x],2], Dynamic[x]}]

Again, there is a convenience for creating a collection of setters all tied to the same variable: (RefLink[SetterBar, paclet:ref/SetterBar]). (RefLink[SetterBar, paclet:ref/SetterBar]) uses a different default setting for the (RefLink[Appearance, paclet:ref/Appearance]) option to (RefLink[Setter, paclet:ref/Setter]), and so its appearance may be different on different platforms. Given its default appearance, you can think of (RefLink[SetterBar, paclet:ref/SetterBar]) as a disembodied (RefLink[TabView, paclet:ref/TabView]) control.

DynamicModule[{x},{SetterBar[Dynamic[x],Range[10]], Dynamic[x]}]

Here is an example that uses graphical labels for the setter bar.

DynamicModule[{func,data=RandomReal[{0,10},{100,2}]},Column[{
SetterBar[Dynamic[func],(# -> Graphics[#[{0,0}], ImageSize->20])& /@ {Point,Circle,Disk,Locator,Rectangle}],
Dynamic[Graphics[{Opacity[0.5],func /@ data}]]},Center]]

Note that (RefLink[RadioButtonBar, paclet:ref/RadioButtonBar]) and (RefLink[SetterBar, paclet:ref/SetterBar]) accept the same (RefLink[Appearance, paclet:ref/Appearance]) settings of "Horizontal", "Vertical", and "Row" that (RefLink[CheckboxBar, paclet:ref/CheckboxBar]) and (RefLink[TogglerBar, paclet:ref/TogglerBar]) do.

PopupMenu and ActionMenu

You have seen how to create and use radio buttons. But when there are more than just a few radio buttons, they can become quite awkward to use. Another control that lets you choose one element out of a set is the popup menu. The (RefLink[PopupMenu, paclet:ref/PopupMenu]) function has exactly the same syntax as (RefLink[RadioButtonBar, paclet:ref/RadioButtonBar]) and (RefLink[SetterBar, paclet:ref/SetterBar]) and provides the same functionality, except with a different interface.

DynamicModule[{x},{PopupMenu[Dynamic[x],Range[10]], Dynamic[x]}]

(RefLink[PopupMenu, paclet:ref/PopupMenu]) can also take the symbol (RefLink[Delimiter, paclet:ref/Delimiter]) in place of an item, which will draw a rule between two items. This is useful for visually grouping like elements. Just like a system popup menu, the delimiter cannot be selected or displayed in the collapsed popup menu.

DynamicModule[{x},PopupMenu[Dynamic[x],{1,2,Delimiter,4,5}]]

The syntax also allows you to separate the value assigned to the variable from the display in the menu. For example, here is a menu that associates numbers with the variable x, but that displays actual words on the menu.

DynamicModule[{x},{PopupMenu[Dynamic[x],{1->"Unity",2->"Even Prime",3->"Smallest Odd Prime"}],Dynamic[x]}]

Notice that once you choose something from a popup menu, the popup menu will remember your choice. Not only is it displayed in the collapsed popup menu, but on some platforms it is also marked with a check mark when the menu is expanded or popped up.

To further customize a popup menu, you can specify a label to display if the value of the dynamic variable is not one of the values listed in the second argument. You do so via the optional third argument.

DynamicModule[{x=""},PopupMenu[Dynamic[x],CountryData["Countries"],"Choose one…"]]

Finally, the fourth argument can specify an arbitrary display for the (RefLink[PopupMenu, paclet:ref/PopupMenu]) when no one is clicking on it. Using the fourth argument will prevent the menu from drawing any of the system-specific hints that it would otherwise use, like a control frame or color, so it is up to the developer to make the user want to click on the custom display.

DynamicModule[{x},PopupMenu[Dynamic[x],CountryData["Countries"],"Choose one…","Click here"]//Framed]

There is another kind of menu whose purpose is not to provide a radio button-like choice, but rather to perform the action associated with the selected item. In the Wolfram Language, this construct is known as (RefLink[ActionMenu, paclet:ref/ActionMenu]). You can think of (RefLink[ActionMenu, paclet:ref/ActionMenu]) as a sort of multi-button that evaluates one of several functions depending on which menu item you choose. It also has some of the same caveats as were discussed for (RefLink[Button, paclet:ref/Button]), such as its action's being effectively invisible except for side effects.

DynamicModule[{x=0},{ActionMenu["click", {"one":>(x=1),"two":>(x=2)}],Dynamic[x]}]

Note that the syntax for (RefLink[ActionMenu, paclet:ref/ActionMenu]) uses (RefLink[RuleDelayed, paclet:ref/RuleDelayed]) (:>) to prevent the actions from evaluating until they are actually chosen by the user. That means that, unlike (RefLink[PopupMenu, paclet:ref/PopupMenu]), specifying labels is not optional for (RefLink[ActionMenu, paclet:ref/ActionMenu])—they are an integral part of the syntax.

(RefLink[ActionMenu, paclet:ref/ActionMenu]) also has an (RefLink[Appearance, paclet:ref/Appearance]) option that can be used to change the overall display of the menu. Here is a simple (RefLink[Manipulate, paclet:ref/Manipulate]) that demonstrates some of the more useful appearances.

Manipulate[ActionMenu["click", {"one":>(x=1),"two":>(x=2)}, Appearance -> a],{a,{Automatic,"PopupMenu","Button","Framed",None}}]

Finally, note that (RefLink[ActionMenu, paclet:ref/ActionMenu]) takes the same (RefLink[Method, paclet:ref/Method]) option (RefLink[Button, paclet:ref/Button]) uses to determine how to evaluate its actions. With the default option setting (RefLink[Method, paclet:ref/Method])->"Preemptive", the action will be evaluated immediately, but will be aborted if the evaluation requires more time than is specified by the (RefLink[DynamicEvaluationTimeout, paclet:ref/DynamicEvaluationTimeout]) option. An (RefLink[ActionMenu, paclet:ref/ActionMenu]) with actions that will take a noticeable length of time should instead use the option (RefLink[Method, paclet:ref/Method])->"Queued" to specify that the evaluation should be put into the regular evaluation queue and allowed to run to completion.

InputField

The (RefLink[InputField, paclet:ref/InputField]) control is unique in that it allows the user to enter any expression at all into it. In its simplest form, it just associates the given expression with the specified dynamic variable.

DynamicModule[{x},{InputField[Dynamic[x]],Dynamic[x]}]

However, (RefLink[InputField, paclet:ref/InputField]) also has a unique set of problems associated with it. For instance, depending on your application, you may want an input field that allows only numbers, only strings, or arbitrary typesetting or expressions. There are a couple of ways to do that. The easiest way is to specify one of the predefined types for (RefLink[InputField, paclet:ref/InputField]) in its second argument. Input fields of type Number do not allow typing anything except characters you would find in a number.

DynamicModule[{x},{InputField[Dynamic[x],Number], Dynamic[x]}]

Note that arbitrary expressions can take up arbitrarily much screen real estate, and (RefLink[InputField, paclet:ref/InputField]) by default will grow to accommodate it. The (RefLink[FieldSize, paclet:ref/FieldSize]) option lets you specify a minimum and maximum size for both the horizontal and vertical dimension of an (RefLink[InputField, paclet:ref/InputField]). By default, an (RefLink[InputField, paclet:ref/InputField]) is restricted to be exactly 20 ems wide, but as tall as it likes.

DynamicModule[{x=Range[100]},
InputField[Dynamic[x], FieldSize -> {{20,20},{1,Infinity}}]]

Another option that is more relevant for (RefLink[InputField, paclet:ref/InputField]) than most other controls is (RefLink[ContinuousAction, paclet:ref/ContinuousAction]). By default, InputField does not commit to its new value until you press the Enter or Tab key. However, for an InputField of type Number, String, and Boxes, you can set (RefLink[ContinuousAction, paclet:ref/ContinuousAction])->(RefLink[True, paclet:ref/True]) to automatically commit to the new value after every key press.

DynamicModule[{x=1},Panel[Grid[{
{"Not continuous:",InputField[Dynamic[x],Number]},
{"Continuous:", InputField[Dynamic[x],Number,ContinuousAction -> True]},
{"",Dynamic[x]}}]]]

With (RefLink[ContinuousAction, paclet:ref/ContinuousAction])->(RefLink[True, paclet:ref/True]), you can also use the second argument of (RefLink[Dynamic, paclet:ref/Dynamic]) as described in "Introduction to Dynamic" to specify your own filters for what characters a user is or is not allowed to type. For instance, this (RefLink[InputField, paclet:ref/InputField]) uses (RefLink[ToUpperCase, paclet:ref/ToUpperCase]) to coerce its input to upper case.

InputField[Dynamic[str,(str=ToUpperCase[#])&],String,ContinuousAction -> True]

Finally, here is a simple example that builds a new control that combines a frameless input field and a popup menu.

popupField[Dynamic[var_],list_List]:=
Grid[{{
InputField[Dynamic[var], Appearance->"Frameless"],PopupMenu[Dynamic[var],list,0,Opener[True, Appearance->Small]]
}},Frame->All,FrameStyle->Gray]

DynamicModule[{f},Column[{
popupField[Dynamic[f],{Sin,Cos,Tan}],
Plot[f[x],{x,0,10}]//Dynamic},Center]]