Tutorial 9: Mouse Drawing
In the previous tutorials, we've looked at a set of basic objects that we use all the time for constructing patchers in Max. In this tutorial, we'll use these objects (and a few more) to actually control something (in this case, drawing). We will look at a few ways to manipulate messages by routing them (using the gate object) and manipulating lists (using the pack and unpack objects). We will also query the state of the mouse to change the way that our patch works, and we will learn more about getting information on individual objects and changing the appearance of objects and patchcords. We will use these new objects and techniques to control the lcd object, which allows us to draw simple two-dimensional graphics inside of Max.
One of the most powerful aspects of Max is the ability to create small segments of programming that perform specific functions, and having the ability to route messages to the appropriate portion of a larger patcher. Intra-patch routing is key to that power, and the gate object provides that functionality in a very flexible way. It is also useful to build complex messages on-the-fly, so we can control complex patch processes with relative ease.
The pack and unpack objects are used to create list messages and to split them into their individual components again. Lists are the key to working with objects that require more complex messages, and it's often necessary to construct and deconstruct lists from smaller components (integer and floating-point numbers, for example).
Finally, we will dig into getting more information on object messages. We'll also learn how to color and manipulate patchcords. Visual cues help us figure out other people’s patch functionality, and make patches more readable when we share our patches.
To open the tutorial patch, click on the green Open Tutorial button in the upper right-hand corner of the documentation window.
Getting more info
Before we begin looking at what our tutorial patcher does, let’s take a short diversion to look at some of the ways we can get information about the objects that we have in our patch. Unlock the patcher and move your mouse around the objects in the patch. You’ve probably noticed that when we place our mouse on an inlet or outlet, a small box is displayed with information about the use of that inlet or outlet. This assistance text is provided as a reminder for the programmer of what that inlet or outlet does in an object. You will also notice that a small circle is displayed around the inlet/outlet.
If we hover the mouse over the left edge of an object, we see a small circle with a triangle. Clicking on this will open the Object Action Menu, which shows (via submenus) the state of the object's attributes, all of the supported incoming messages, as well as shortcuts to view the object’s help file, reference pages and even to search our system for relevant matches in the file browser. This provides a greater level of detail if we need to know details about the exact use of the object. This information is also available in the Messages and Attributes segments of the circular menu.
There are other options for on-the-fly information. Select Clue Window from the Window menu of Max; a small window will be displayed. Now, when you hover the mouse over an object, we will see a brief explanation of the function of the object. Using the clue window to view the use of objects is a great way to examine the objects used within a more complex patch.
More about objects and patchcords
If you look at the objects in this tutorial patcher, we notice that the patchcords look a little different than the ones we've seen earlier. First of all, a number of the patchcords have intricate paths made of several segments; in addition, some of them are different colors. Let’s look at some of the ways we can manipulate the patchcords themselves. Under the Options menu in Max, check the option Segmented patchcords. This allows us to create patchcords that have bends in them. We can delete a patchcord by selecting it and hitting the Delete key, or by choosing Delete from the patchcord menu. Delete one of the patchcords connecting the message boxes to the gate object at the top-left of the patch.
Now, reconnect the message box to the gate, but instead of making a direct connection between the two, make a segmented patchcord by clicking the outlet of the message box and then releasing the mouse; we can add segments by clicking the mouse anywhere while we draw the patchcord; we finish the connection by clicking the inlet of the destination object (the gate). Whether you use straight or segmented patchcords is largely a matter of personal style, but often you can sometimes make a patch look cleaner by using segmented patchcords.
Max also can help us clean up our patchcords. Click on the patchcord and hit Shift-Command-Y on the Mac, Ctrl-Shift-A on the PC (alternately, you can select the Route Patch Cords function under the Arrange menu in Max). Max will segment and reroute the patchcord to avoid overlapping objects. A simple Command-Y gets a cord with a single bend along the shortest path. We can also select several patchcords by holding the Shift key while clicking on patchcords (or the Option key while dragging across cords)- the command sequence will then reroute all of the selected patchcords. There is no difference whatsoever between a regular and segmented patchcord in terms of how messages are passed between objects.
Finally, let’s look at Max’s ability to change the color of objects and patchcords. We can select an object or patchcord (by clicking on it) then select Format from the upper toolbar. This will display new toolbar with icons for individual elements of objects—background, text, borders, whatever it's got. Selecting the appropriate icon will let you color (for instance) the blink of a button. We've been coloring objects as we introduce them in the tutorials; as you can see, it's a great way to focus attention on important items within our patch. (Note that there is a consistent gold color for the objects in a patch you will be instructed to manipulate.)
In addition to carefully coloring each object, you can save the color scheme as a style. The text at the left of the format toolbar is a dropdown menu. If a colored object is selected, you can define its color scheme as a style with a distinct name. These names will then be stored in the patch so you can easily apply them to other object of the same type. You can even save your styles in a library so they will be available in all of your patches. Finally, there are several style sets supplied if you feel the default look is a bit austere.
Working with the gate object
Now lets look at what the patcher does. In our tutorial patcher, we find two small patches (on the left) and one very large patch. The patch at the top left is where we will start.
This patch shows the gate object in action. The gate object is one of the most important objects used for dynamic message routing within Max. We will start by clicking on the message labeled (the middle box), then changing the value of the number box attached the right inlet of the gate. When we do this, we see that the value of the number box is sent out the left outlet of the gate (outlet ). If we click on the labeled and alter the number box again, we see that the changes are now sent out the right outlet of the gate (or outlet ).
As we can see, the number sent into the left inlet determines the routing of the message received in the right inlet; in essence, the left inlet determines which outlet is opened. Now, click on the message labeled and change the number on the right. The message never makes it out of the gate – the message has closed all of the outlets. This is useful for situations where we want to suppress messages within our patch, for example when we need to selectively enable and disable numbers flowing from one part of our patch to another.
As an exercise, change the gate object to have a for an argument (it currently has a ). We see that the object changes – it now has four outlets. The argument to gate determines the number of outlets that the object has. If we add a few more messages to the left inlet (by adding a and option to support the new gate outlets) and attaching number boxes to the new outlets, we can see how easy it is to expand the routing matrix supported by the gate object.
The next part of patch that we will look at is just below the gate – it uses the unpack and pack objects to split and reassemble lists of numbers, and the prepend object to place a message selector (a symbol) in front of the list. The two message boxes contain two-number lists; when we click on them, we see the two number boxes connected to the unpack object display the individual numbers within the list. The unpack object has taken the incoming list and split it into individual numeric messages. Since lists are often used to create complex messages, we often use the unpack object to unwrap these lists into its individual components (called atoms).
After the number boxes display the messages, they send out their contents into the pack object below, which reverses the process by combining them back into lists that are sent to the prepend object and displayed in the Max Console (via the print object. Notice that only one message is displayed in the Max Console, even though the pack object received two messages (one from each number box). This is because the pack object (like most other objects in Max) will only produce a message when the leftmost inlet receives a message. The patch editing environment provides a clue for this: if we unlock the patch and hover the cursor over the right inlet, we see that it displays a blue circle – meaning that it is a cold (non-message producing) inlet. Hover over the left inlet and we see it circled in red; it is a hot inlet, and will cause the object to generate output when it receives a message. We can confirm this by typing other numbers into the number boxes that are sandwiched in between the unpack and pack - only the left-hand number box will cause a list to come out of the pack object.
The arguments to pack and unpack determine both the number of inlets and outlets, respectively, the object will have, but also the type of message that can be sent into those inlets. In our case here, both of these objects are working with two-element lists made up of integer numbers (signified by the use of as an initial argument). If the list we were making required floating-point numbers, we could have used (or any other initial floating-point value) as an argument; similarly, if a symbol (a word) was needed in the list, we could have used the letter (or any symbol); types of data can be mixed and matched within a list.
Notice that the prepend object places the word in front of the list of numbers coming out of the unpack - this symbol can be any word we like, but in many cases in Max we use prepend to place a message selector at the start of a list before sending it into an object that has a special use for that message.
The lcd object
The large rectangular object at the right of the patch is an lcd (liquid crystal display) object: we can use this object to draw pixels, lines, shapes, text, and other simple two-dimensional vector graphics. If you drag the mouse in this area while holding down the mouse button, we see that it draws lines wherever you go. Release the mouse button, and the drawing will stop.
If you hold down the shift key, option/alt key or a combination of both, the lcd object draws different shapes under the mouse rather than lines. There are three colored message boxes above the lcd that can be used to change the foreground color of the drawing (using the message), and another box (to the right) that will send the message to the lcd, erasing its screen.
One of the key sections of this patch is the handling of the shift and option/alt keys; this is done by the modifiers object, which is polled using the metro, and reports the current setting of the various modifier keys on your keyboard. In this case, we use the outlets that report the shift and option/alt keys; we multiply the option key's state by and add it to the state of the shift key. The result is that shift alone will give us the value , option/alt alone will give the value , and the combination will give us . If no modifier keys are depressed, the value will be . This type of patch circuit is perfect for controlling the state of the gate object below.
In addition to providing a drawing surface, the lcd object can give us the current location of the mouse in a manner analogous to the mousestate object, only relative to the position of the lcd in the patch. Sending the message to the object allows us to get mouse coordinates regardless of whether or not the mouse is actually clicked inside the lcd (we enabled idle mousing when we turned on the toggle box, above).
These coordinates are provided by the second outlet of the lcd object – we can see the values (a list of two numbers that represent the X and Y coordinates within the LCD object) in the number boxes at the bottom, after they've been split apart by the unpack object. This list is also sent to the right inlet of the gate object; we’ve colored that patchcord red to make it easy to see.
The objects named patcher objects. These contain subpatches that generate the shapes shown in the lcd. By routing the mouse coordinates to different patchers, the gate object now controls what type of drawing will occur. If no modifier keys are depressed, the gate receives a and none of the drawing routines are used, though we can still click-drag inside the lcd to draw lines. If shift, option/alt, or both are depressed, the gate routes the mouse location to the appropriate seubpatch.are
In each of these subpatches, the X and Y locations are run through unpack objects to get the coordinates individually. They are then used to create a properly sized shape. In the (shift) case, a value of is subtracted and added to both coordinates and sent into a pack object in the order:
X-10 Y-10 X+10 Y+10
This list of four values is then sent to a prepend, which places a symbol at the front of the list. The lcd object supports a number of drawing commands which do different things; in this case, we're instructing our lcd to draw rectangular frames by providing it with a message followed by four arguments - the left, top, right, and bottom boundaries of the rectangle we'd like to draw.
Looking at the other two pieces of drawing code, we can see that they work in similar ways. The middle outlet of the gate object (responding to the option/alt key) draws oval-shaped frames (the message) that are 10x10 pixels in size (notice the + and - objects). The third drawing alternative (for when both shift and option/alt are held down) draws filled in rectangles with rounded corners ( ). In addition to the coordinates of the rectangle, two additional number boxes are sent into the packobject - these control how rounded the corners are.
When the coordinates are created and determined (using the math objects and pack) and given a message selector to determine the drawing routine (using the prepend object), the message is sent back into the lcd object. In order to easily see this message routing, we’ve colored the drawing command patchcords in blue. The frgb message boxes are also colored to match the color it will tell the lcd to draw with. These are examples of using object and patch cord coloring to make the function of a patch more obvious.
There have been several different (but important) topics covered in this tutorial. We see how the gate object can be used to activate message passing to sections of your patch. We’ve also seen how to use the unpack, pack, and prepend objects to build and parse complex messages. We’ve also seen how to color and manipulate patchcords and objects to help make patches and message routing more easily visible. Finally, we've seen how to use the lcd object for simple drawing.