Now that we have some basic understanding of the Quartz Composer Interface, let's build upon what we have now and turn it into a rudimentary window manager. If you had some difficulty in solving the previous exercises, which was purposefully set a bit tough, we have put up a detailed discussion of the answer here. Here is what the solved exercise looks like:
You might be all excited to start building a window manager, but before we do so, lets go through a customary routine you have to follow when dealing with projects in Quartz Composer that change over time. Make sure you have the project that we left with in the previous chapter at hand. If you have messed up with it, you can download a fresh copy here. Open the project and make your viewer window active. Now, toggle the button. Stop your running composition by clicking on the stop icon on the menubar and press the Run button. You will witness that the button gets untoggled.
If this behaviour seems quirky, recall from the 0s and 1s section in the previous primer that Quartz Composer defaults all values to 0 when the project begins. By stopping the viewer and playing it again, we are resetting the time of the project to 0. It also seems to have the benefit of cleaning up the memory that was used in the previous program execution. You might want to keep this reset routine in mind when working with compositions that have timing functions like the this one.
So far, we were using a bulb metaphor on the button so as to illustrate the concept of 0s and 1s. In this tutorial, we are going to deal with windows. Lets replace the bulb glyph with one that would be more in-line with the exercise. Here, take these two button states and replace them against the button states with off/on bulb. We have also provided the Sketch resource aside in case you want to have your own twist to it. It also includes the window sprite required to complete this exercise. Once you are done replacing the buttons, the ground is set to bring in the window to the composition.
To get the window on the screen, drag and drop this Window's image on to the editor. Bring in a new Billboard patch, change it's Dimensions Mode to Real Size as described previously and connect the window image to the patch.
You might notice that the Window isn't as pixel precise as you want it to be. If you have a pixel precise window, try resizing your view window to an odd resolution like 791×599 and you will see that the window becomes blurry. This can easily be fixed by setting the Pixel Aligned port on the Billboard to 1. But a trade-off is that, when you animate the window the animation will only progress in steps of single pixels as this option is turned on. This gives off a jagged feel to the animation. There is a way to hustle best of the both world which we would eventually be revealing. So, for this tutorial, let's set the Pixel Aligned value of the billboard to 0. Set the size of the viewer window to an even resolution of 800x600 so that it isn't blurry.
As soon as that is done, you will notice that our Window sits on top of our button, hiding it. This works well for us but what if this was not the intended behaviour and you wanted the window to go behind the button ? This can be manipulated with the help of the numbered drop-down on the top right corner of the blue patches. Click on the number with arrows on the right to access the layer position of patch. Something to note here is that this feature is available only for patches that have output which are colour coded blue in Quartz Composer.
Try changing the numbers of your blue patches around. One thing you might want to try is to progressively change the layer number of the clear patch and understand what's going on. If you incrementally increase the layer number of the patch, you could see the darkness approaching towards you engulfing the layers that were on it. Though it's a hyperbole and quite likely feels like a pointless exercise, when you start building your projects, you will find some of your images gets missing in the middle of the project. Recall this instance of darkness engulfing and you could quickly retrace it to a wrong ordering of the clear patch. When you finish tinkering with the layer order, return it to the original order: Clear is Layer 1. Background is 2nd. Button 3rd and Window, the topmost.
Now that we have got the window on the screen, it's time to link it to the button. Reset your viewer by going through the routine mentioned above. You can always make use of the sequence of key presses: Cmd+. and Cmd+R to accomplish the routine quickly. Drag out a new noodle from the Output port on the Toggle patch by clicking on it and connect it to the Enable port of the Billboard to which the Window Image is connected. You will notice that there's now two noodles coming out of the Toggle patch.
This is quite frequently done in Quartz Composer. You would have already come across this if you had finished the exercise in the previous primer. You can always drag out multiple noodles from the output port of the patches, but can only connect it to a single input port. There is a keyboard shortcut you can make use of when connecting multiple ports from the same port. Before you make the first connection, hold down the Alt key and then make the connection. This ensures that a copy of the noodle remains with your cursor when you make the connection. Use this noodle to make the connection to the other port. You can keep holding down the Alt key to retain the noodle to make more connections.
As you make this connection, if you had the Viewer window beside you, you will notice that the window abruptly disappears. If you can read together two things we discussed previously, you can make sense of what is going on: 1) False and True Values are internally represented as 0 and 1 from the Zeros and Ones section and 2) Quartz Composer defaults the output values of patches to 0 as they are introduced in to the composition from the clean slate section. Initially when you make the connection from the Toggle patch, the patch gives out a value of 0 to the Enable port. This means that the billboard would be disabled.
Let's test what we have build so far. Try clicking on the button to toggle the window. As you click on the button the button appears. The same logic we used for the disabled state of the window can be used to explain this. Clicking on the button makes the toggle patch output 1 which is received by the billboard and gets enabled as a result, thereby displaying the window image. Now we have the window appearing alright, but now, the button is getting obstructed by the window that just appeared. We need to think up a way to dismiss it. Since this is an introductory post, let's settle for a simple enough interaction. We will make the window disappear when we click anywhere on it.
We are now at a point in our tutorial, where we have to make a window disappear when we click a button or when we click on the window. This means that we have to detect when either of these happen. The solution is the Logic Patch. A logic gate makes a decision based on the two inputs that you supply it. Let's see how that works with the example of an OR gate. From the patch library, pull out the patch known as Logic, when it lands in your editor, you will see a patch named AND with two inputs and an output. Double click on the label and you will find about half a dozen options pop out. Choose the OR option. This gives us an OR gate in the composition.
An OR gate outputs a value of true when either the first input or the second input is true, the output value will be true. That is, in Quartz-Speak if any of the inputs is found to be 1, OR gate will output 1. This also means if both inputs are 1, the output value is 1. There is no 2 in boolean numbers; things are always either 0 or 1, that is true or false.
Let's now think of how we might use this logic gate to our advantage. We need a window to appear when the press on the button is made and dismiss the window just appeared by clicking anywhere on it. Rewire the connection made from the Mouse Down of the Interaction patch connected to the Toggle patch, to the first input of the OR gate. Drag a noodle from the output port of the OR gate and connect it to the Input Value of Toggle Patch. Reset your composition and test it out. You will see that it has the same effect as the previous setup. This is because essentially the same thing is happening, although there is an OR gate interposed. When a click is made on the button, the first input port receives a 1, which means that OR gate has got one of it's values to be 1 and it outputs a 1 to the toggle patch which makes the window appear. The other input port of the OR gate always remains 0 and hence doesn't play any part in this process.
Let's now bring in an Interaction patch and connect it to the billboard of the Window. After you make that connection, drag out a noodle from the mouse down of the Interaction patch and rig it to the second port of the OR gate.
Toggle with an OR gate
Test out what we have just built. You will see that it works exactly as we wanted, but what's going on in here? Open up the Inspector Window of the logic gate by pressing Cmd + I on it. Now press on the button in the viewer window and you will see that the First operand gets turned on for a fraction of a second. At this point, the OR gate switches the toggle value and makes the window enabled. Now, the Window comes up on the screen obstructing the button. Try clicking anywhere on the Window and you will see that the second operand gets turn on briefly, which toggles the value again making the window disappear. Remember that the OR gate needs any of the values to turn true to trigger the toggle.
And there we have it, the window appears when you click the button and disappears when we click anywhere on the window. Looks like we have made some good progress, but it feels as if the whole thing seriously lacks some oomph. A window that appears jarringly out of nowhere is no fun. It also makes it a bit puzzling for the user to figure out where it emerged from. Let's bring in some animation in to play and see how it eliminates these two shortcomings with a single shot.
Animation in user interfaces should be frugally used. To consolidate the user's mental model of the task or to provide a meaningful feedback, would be some good opportunities to use animation. While the animation we are about to bring in would make our interface look more fluid, consider it only a side-effect, the primary reason we are using it is to reinforce the relationship between the button and the window. If we make it look like the window is emerging from the button, the user will feel to have more control in the interface. With that idea in mind, let's find out how to implement the animation.
For proceeding further in the tutorial, we need to make the size of our Window adjustable. To achieve this, first, unwire the connection from the Toggle patch to Enable port of the Window's Billboard. Bring up the Inspector panel (Cmd + I or Cmd + 1) and make sure that the Window is enabled by ticking the checkbox. Next, bring up the settings panel (Cmd + Shift + I or Cmd + 2) of the Billboard patch of the Window and choose Custom Size instead of Real Size. Now to get the dimensions of the window, pull out a Image Dimensions patch from the Patch library. Connect the Image output port of the Window Image Patch to the Image input port of the Image Dimension patch. Image Dimensions patch delivers what it says on the label. It provides you with the width, height and aspect ratio of your image. With the dimensions of the image at hand, let's meet the patch that is at the core of animation in Quartz Composer
Interpolation patch is commonly used to implement animations in Quartz Composer. It's actually a simple patch that interpolates between two values over a duration. If you inspect the Interpolation patch, you will see that it has got ports called Start Value, End Value and Duration among others. When an interpolation patch is in execution, the Start Value changes to the End Value over a period of time specified in the Duration port. But then, when does it start? This is a tricky bit in Quartz Composer. The time starts at 0 when you run hit Run in the Viewer Window. For example, suppose the start value is 0, end value is 100 and duration is 1. From the start of the composition, exactly within 1 second, the patch counts from 0 to 100.
For our purpose, we will make it count from 0 till the dimension of the window. Drag out two interpolation patches from the patch library. Connect the Width output port of the Image Dimension Window to the End Value port of one of the Interpolation patch and the Height output port to the End Value port of the other. Plug in the results of both of these patches to the Width and Height port of the Window's Billboard respectively:
Interpolation patches for animating both width and height.
In your Viewer Window try clicking on the button, you will be able to see that the window is getting animated from 0 to it's original size continuously. This is because the Repeat Mode of an Interpolation patch is set by default to Loop. When an interpolation patch is set to loop, it loops over a period of time set in it's Duration port. A fun thing to do at this point would be to set the Repeat Mode of both patches to Mirrored Loop which will make the window bounce back and forth. A mirrored loop makes an interpolation run from start value to end value and back repeatedly.
Mirrored Loop in action.
To proceed with the task at hand, let us go in and change the Repeat Mode to None. This ensures that the interpolation patches will run only once. This can be verified by resetting the viewer window and clicking the button really quickly, that is, within 1 second. If you make it in time, you would be able to witness the window animating as it appears. But then the subsequent clicks doesn't entice this behaviour. Seems strange? This has something to do with the timing of patches in Quartz Composer which is the topic of discussion of the next section.
There are three modes to setting a patch's timing. The first being Parent which means that the patch will inherit time information from it's parent. There's local mode which means that the time will be generated locally, that is, whenever the patch gets enabled, it's time starts from 0. The last option is External which makes the patch dependent on an external source for it's information. All the patches in Quartz Composer are set as default to have the Timebase as Parent.
In our case, when the Interpolation patches are set to have their Parent's timebase with a duration of 1 second, they will start animating from time 0 to till the first second. This means the window will resize up until the first second after we hit Play in the viewer window. Whenever the viewer window is reset, the composition's time again starts running from 0. This is exactly why our interpolation patches where animating if we clicked it only in time and only once. Now that you know the mechanics of what is going on under the hood, you can increase the duration to something like 10 seconds and try to click the button after you reset the composition. Only this time, you don't need to be as much of a quick gun as before, you have a window of 10 seconds to see the window animation. Once you have fully grasped what was told above, you have acquired the knowledge to bend time to your will! But only in Quartz Composer.
To achieve what we were after, we need to animate the window as it emerges and also as it disappears. This means that we need to set the timing of the Interpolation patches externally. Let's switch the timebase of both the Interpolation patches by right clicking on it and choosing Timebase > External. This causes the patches to have a new port called Patch time on the top. This is the port to which we need to plug in an external time source.
In our case, we have the toggle patch outputting the value 1 when the window appears and 0 when the window disappears. This might seem like a good source to provide us with time. Let's try connecting the Output port of the Toggle patch to the Patch Time of both the Interpolation patches. Once you have made the connection to both the Interpolation patches, reset the Viewer window and test out our rig. You will find that it took us nowhere! We are right where we started without animation.
Our assumption has gone wrong, the toggle patch doesn't seem to be a good source of time. From our experience so far, we know that the toggle patch is pretty instantaneous in switching it's values out when a click is made. It swiftly swaps between these values as we click on the button and the window. We perceive time to have a continuous flow; but what's happening in our case is that we are jumping from second 0 to second 1 and back as we interact with the button and the window. This means that the interaction patch gives out 0 for height and width at the 0th second and in the next instant it receives second 1 to it's Patch time port which makes it output the original dimensions of the window as we have set the duration to be 1 second. The window has 0 height and width when it's not toggled and when the click on the button is made, the next instant, the patch time becomes 1 and the window acquires it's original dimensions. What we are lacking here is a patch that would ease a transition from 0 to 1. We need a patch that would take us from 0 to 1 smoothly. Having framed the question like this, it's easy to find the answer in the patch library.
Smooth patch smoothes an instantaneous value over a period of time. Think of it like an interpolation patch, but that the start value and end value are assumed by the patch from the incoming value. What this means is that, whenever a value turns from 0 to 1, the smooth patch smoothes it out over a period of specified time. The same smoothening function acts out when the value goes back from 0 to 1. Let's now make use of this fact to trigger our timing. Bring in a Smooth Patch from the patch library. Rewire the output port of the Toggle Patch to the Value port of the Smooth patch. Connect the Smoothened Value output port of the Smooth patch to the Patch Time of both the Interpolation patches.
Interposing Smooth patch between toggle and the interpolation patches.
We are almost there. Everything works as expected. Now, we shall add some subtle details to the animation that would make it feel more responsive. Select one of your interpolation patches and open the settings panel. You will see the two radio buttons which enables you to modify the graph. Choose the customized interpolation curve option. Now, the graph beneath would become editable. Add a point by clicking anywhere on the curve. You can see that the location of a point is determined by two values named T and V. These stand for Time and Value respectively. Set the values as 0.378 for the Time and 0.647 for the Value. Similarly, add another point on the graph and set it values as T:0.543 V:0.911. Repeat this process for the other interpolation patch. Now test out your composition, you will see our window has got a pop effect.
These are not any magical bullet values. We arrived at it by experimenting different values. You can arrive at similar or better effects, just by playing with the curve.We feel that these sort of subtle effects in the interface are what reflects your craftsmanship on the interface. Play with the composition and let us know if you turn up with something nifty.
Here is the final Quartz Composer project :
As always, any comments, critiques or corrections are always welcome. In the next interface we will learn how to move the window around. Stay tuned.
Sign up to stay notified about the next post