Tutorial 7: Numerical User Interfaces
Sliders and Dials
In this tutorial, we will work with several user interface elements that provide numerical display and editing. We will use both messages and the object inspector to change the appearance and behavior of objects in order to make them work as we wish.
Numerical display and editing is at the heart of Max patching. Whether data comes from sensors, MIDI devices or just from moving on-screen controls, numerical data is easy to test, manipulate and use for program control.
To open the tutorial patch, click on the green Open Tutorial button in the upper right-hand corner of the documentation window.
Numeric UI Objects
Open the tutorial patcher. At the left side of the patch is a set of interconnected message boxes, sliders, knobs and number boxes. The basic "slider" object in Max is called a slider, and can be oriented horizontally or vertically, depending on what we need for our patcher interface. (Just use the resize spot at the lower right to drag it into the shape you want.) The "knob" is called a dial object.
Click and drag on the "thumb" of the slider objects to see the results displayed in the connected number boxes. The output of a slider is an integer number based on the range of the slider. Both the vertical and horizontal slider perform identically.
The dial next to the vertical slider performs a similar function; however, in its current configuration, you need to move the mouse pointer in a vertical motion to change the position of the knob’s wiper. This is something we will look at changing later in this tutorial.
Click on the button just above the horizontal slider – it doesn’t seem to perform any function. However, if we change the number box connected to the slider, then click the button again, we will see that when a slider receives a , it responds by outputting its most recent value. Thus, a slider acts like a number storage tool as well as a numerical editor.
Finally, let’s unlock the patch. If we put the mouse pointer near the bottom-right corner of a slider or dial, we see a small resize box appear, and the cursor changes to reflect that we can resize the objects. When we click and drag the resize box, the shape of the object changes, but the function of the object stays the same. In fact, this is the way to create a horizontal slider, as the default shape is vertical. This allows us to change the layout of our patch for convenience without changing the way our user interface elements operate.
Changing UI object behavior
All three of our user interface objects share the same output range:through . Obviously, this is not the behavior we would always (or even normally) want. By default, these objects output numbers in the range of to (which mimics the MIDI number range); this range can easily be changed using messages to the object.
Above the objects are some message boxes that produce messages based on numbers coming in from attached number boxes. As we’ve seen in earlier tutorials, this is a mechanism to send commands to another object; in this case, we will use them to change the behavior of the slider and dial objects. If we change the first number box (connected to the message) to and then move the sliders or knob, we see that the range has changed: you can now produce output from through . Why not ? It is because the message determines the number of discrete steps for the object. If the starting step of is included, steps will give you a maximum value of .
Next, let's adjust the number box which triggers the message. If we change this to , the slider objects and the dial now output messages in the range of to . Using the and messages in tandem allow us to set the objects to output whatever range of values we need for our patching.
If we change the third number box (connected to the message) to , the output changes to output the range from to , in steps of . This is based on the way in which the interface objects calculate their output: the objects maintain an internal value from to the range ( - - 1). This is multiplied by the value, then offset to match the value. This means that the output will always have step sizes of , even as the value goes through .
number box options and the Inspector
On the right-hand side of the patch is a diamond array of number boxes, each one providing a different display format. The top-most number box is familiar to us – a decimal format number, with a triangle that helps us recognize this as an editable number box. Connected to this are two number boxes with different display formats: the left box displays information in hexadecimal (base-16), while the right box displays the information as if it were an incoming MIDI value.
The bottom number box shows a change in display characteristics: the number is in a bold font, and there is no triangle on the left of the box. This may be useful if you want to see more of the number in a limited space, or if you want to imply that the value shouldn’t be edited.
All of these variations on the number box are based on changes in the attributes of the object. Attributes are changed using the object inspector, a window containing all of an object's attributes, and an interface for editing them. Unlock the patch and click the inspector icon in the window toolbar to open it.
The initial display of the inspector shows all of the available attributes, sorted by type. There is also a set of tabs across the top of the inspector that allow us to limit the attributes that we see. The "Display Format" attribute has a discrete number of values; you can see the available formats by clicking on the current value. The options are "Decimal", "Hex", "Roland Octal", "Binary", "MIDI", and "MIDI (C4)". These are all variations on decimal display that may be useful, depending on the values you are entering or displaying in a number box.
When we click on the "All" tab, we see all of the attributes that affect the appearance and operation of the number box. Options include "Draw Triangle", something we saw disabled in the bottom number box in our patcher. Turn this on and off in the inspector, and notice that there is an immediate change in the object; changes to inspector values cause instant changes to the object.
The names used by the inspector do not necessarily match the messages used to control the object. How do we know what message might match a particular attribute? The easiest way to create a matching message is to click on the name of an attribute and drag it into an unlocked patcher. The name will be transformed into a message box formatted with the proper message, offering a shortcut when you want programmatic control of attributes.
Using the inspector
Let's unlock the patcher and create our own small user interface. Select a slider, a dial and a number box from the top patcher window toolbar palettes. Resize them to be different sizes, and move them around to make an attractive layout. Note how the slider switches from a vertical to horizontal orientation depending on the aspect ratio (height versus width). Connect the objects to see how they interact, and use the objects as both display and editing tools. Then, for each object, open the inspector and make some changes in appearance. Change the colors, and (if you like) change their behavior. When you are done, lock the patch and make sure the objects look and act as you expected.
Visual display and editing of numerical data can take many forms. We’ve seen how to use slider and dial objects, and how to display numbers in various formats within the number box. We’ve also changed the behavior of objects using both messages and the Object Inspector. Since using numerical data is so important in Max programming, it is helpful to have many ways to show and alter this type of data.