Having made it this far in the Grand Tour chapters, it’s time for a challenge. Test yourself on what you have learned about Prograph and the Application Builder by extending the Folks Database. Along the way in the challenge you are introduced to exciting additional features of Prograph.
Over the next several pages, you are given a series of design objectives and helpful points of information. Use all you know about Prograph to solve these development challenges while practicing your basic skills in using the Prograph editors and*156* runtime debugging facilities. When you have solved a challenge, or if you get stuck, turn the page for a solution.
Of course there are always many routes to the same objective in programming, so don’t be surprised if your solution works but varies from the solution presented. This implementation flexibility is part of the power of Prograph.
First, here are some basic pointers that apply to all the challenges.
q The*344* Trace *628**1103*item in the Exec menu causes your application to run entirely in step mode. Trace opens an execution window on everything, allowing you to watch your methods *683*execute. It even traces into local methods as they run.*723*
q Don’t forget about the Primitives item in the*449* Info… dialog. Most of the primitives have logical names that give strong indications of what they do. The text descriptions give a helpful summary of a primitive’s function, but don’t neglect learning to read the information lines that describe the number and data type requirements for the terminals and roots of a primitive operation.
q *1094*Use the interactive, incremental editing features of Prograph, which often give you more success in developing a complex method on the fly by allowing you to inspect data *1142*values going in and coming out of operations during runtime. This approach helps you decide what to do next and lets you correct small errors a step at a time. This is often more productive than trying to write an entire method before you run it. Developing too much code before you run it can lead to multiple simultaneous errors and a frustrating attempt to fix the whole wretched mess.
q *274*Use comments*173*. Comments, especially those on terminals and roots, can be extremely helpful when you create locals, and also when you create a new method by first putting a user-defined method operation in an existing method. When you double-click to create the as-yet-undefined method, the comments transfer into the case window of the new method. These comments can be very helpful in keeping you organized.
q Save your work and explore files from the Learning Prograph folder. Much useful code is found in the examples. Check them out, and do not hesitate to use copy and paste or selective loading to bring relevant classes or methods into your Folks Database. After all, code reusability is a key benefit of object-oriented programming.
Now, on to your first challenge.
Challenge #1
Your Objective: Use the Application Builder to add an Edit menu with Cut, Copy, and Paste functions for text selections.
Tips and Hints
q There are methods for the basic cut, copy, and paste functions in the Menu class.
q After adding the precooked methods, use the Trace function to explore how they work as you cut, copy, and paste names in the Name field of the Folks Database window.
q Don’t forget to make sure the new menu is added to the*1039* Active List. If you leave it in the Library, it exists but is not visible or functioning in your application.
Solution to Challenge #1
 
Solution Comments: This was an easy one to get you going. Notice that the data-determined *701*method reference, /Paste, accesses the supplied generic method in the Menu class. This is because the default class for selected menu items is the Menu class. An explicit class reference, Menu/Paste, works, too.
Challenge #2
Your Objective: Enhance the Folks Database such that when you double-click on a name in the scrolling list, you get a *153*dialog that allows you to enter, inspect, and update a phone number for that person.
Tips and Hints
q Add a phoneNumber attribute to the Person class.
q Add a phoneNumber method to the Person class. Using the Application Builder Window editor and its Scroll List editor, set Person/phoneClick to be the Click Method of the Name List scrolling list. Use phoneClick to check whether you got a double-click on an element in the scrolling list, and then call the phoneNumber method. This divorces the phoneNumber method from interface considerations, which will be useful in some of the following challenges.
q There are four roots on the input bar of a Scroll List click method. (Inputs for all Application Builder methods are given in chapter 5, “System Classes,” in the Reference manual.) A Scroll List item responds to both a single click and a double-click. To distinguish between the two, use the primitive is-double?, which takes as its input a Macintosh Event Record, which in this case is provided by the fourth root on the input bar.
 
q In chapter 2 you worked with a “Next Case on Failure” control to check for a non-NULL name. A similar control, “Terminate on Failure”, can be attached to the is-double? boolean primitive: when fired, it terminates execution of the method.
q The third root on the input bar of phoneClick is an integer which identifies the list position of the selected name, relative to the front (or top) of the value list attribute of the Scroll List. Pass this value on to the phoneNumber method.
q The Person objects in the People persistent are in the same order as the names in the scrolling list’s value list.
q The get-nth *392**844*and ask *81**836*primitives are useful.
Solution to Challenge #2
 
Solution Comments: This is not the most elegant interface for doing phone numbers, but it gets the job done. Note the use of an attribute value as the default answer for the ask operation. Also, it is a good idea to merge the selected person’s name and number in the ask operation prompt. A personalized prompt reminds you whose phone number is being accessed.
NOTE: If you are running the Person/phoneClick method in Step/Show mode, you will never catch a double-click, since the execution window that pops up in response to the first click will cause the second click to be discarded. This method must run with Step/Show Off to work properly.
Your Objective: It is typical in Macintosh interfaces to have a *264* button that performs a function on a click-selected item in a scroll list in that window. The function is often the same as if that item had been double-clicked in the scroll list. An example is the Open button in a file-selection dialog where double-clicking a file name in the scroll list also opens the file. Add a button*152* called Phone… to the Folks Database window and have it do the same function as the scroll-list click method.
Tips and Hints*169*
q The click method of a button is not the same as the click method for a scroll list. Take the input you are given in the button-click method. Extract the required items to pass along to the phoneNumber method, as if the selected item had been double-clicked and had executed phoneNumber directly.
q If you have a list with a single item in it and you need that item by itself, say as an integer, the*1124* unpack *848*primitive with a single root does the trick. There are a number of other list primitives that allow you to do the same thing in various ways.
q Although the current version of phoneNumber only uses the third root of the input bar, feed the Window and Scroll List items into the phoneNumber operation in the Phone… method. Provide these same two inputs to the phoneNumber operation in the phoneClick method. In the final two challenges you need these inputs to elaborate the phoneNumber method.
q You may need to use the*114* *278*Bring Closer *596*item in the Edit method to force the Add button to become the highlighted*119* default button in the Folks Database window.
Solution to Challenge #3
 
Solution Comments: Folks Database is really starting to look and feel like a Macintosh application. Notice that an *364*explicit-class *705* method reference is used for the Phone… button-click method. This promotes design organization by ensuring that this Person object-manipulating method is found in the Person class. A data-determined *702*method reference, /Phone…, would have put this method in the Button class’s default class, Window.
Challenge #4
This challenge is for System 6 users only, since a System 7 feature makes the objective impossible to attain. System 7 users should read through the challenge and its solution as it contains useful information about synchros
Your Objective: On the Macintosh, menus are not accessible when a modal dialog is onscreen. (Modal dialogs*729* require a response before they let you do anything else.) The Macintosh interface*556* guidelines suggest that when menus are not accessible they be dimmed to indicate they are *594*disabled. *154*Disable the File and Edit menus of Folks Database when the phone-number dialog comes up. Enable them when the phone-number dialog is dismissed.
q Look at the attributes of the Menu class. The enabled? attribute is a Boolean*92* type that can be set with the character strings TRUE or FALSE to enable and disable the menu. The state of this attribute determines whether the menu is dimmed.
q Modify the phoneNumber method to toggle the state of the File and Edit menus on the way into and out of this method. Take the current operations that do the phoneNumber dialog interaction and encapsulate them in a local method. It is then easy to sandwich the menu-management tasks around the local.
q The owner attribute of a window is set to an instance of the Application class. Get the menus attribute from the Application owner and use a list-processing multiplex Set operation to toggle the menus on and off.
q A synchro is a connector between operation icons that specifies which operation should execute before another. Since Prograph methods are data-driven*896*, you do not always know in which order operations execute. Synchros provide this control*685*. To be certain the menus are disabled before the phone-number dialog occurs, a synchro is required.
Create a synchro*1030* by clicking the operation icon that is to occur first. Then Option-drag-click on the operation icon that is to follow. A line of rounded arrowheads is drawn from the first to the second:
 
q Toggle*345* Trace *629**1104*mode to see your menus in action. The execution windowing activity with Trace mode on obscures the behavior of the menus as you pop in and out of the phone-number dialog.
Solution to Challenge #4
 
Solution Comments: A second synchro ensuring that the phone-number dialog occurs before the menus are re-enabled may be required. A topological sort is performed on the graph representation of a method to determine execution order. When multiple equivalent execution-order paths are available, an arbitrary ordering is set.
To check whether a second synchro is required in your phoneNumber method, use Tab to preview the execution order while in the case window. Or run your application and see if the menus are dimmed and reset properly. If not, add a second synchro from the phone dialog local operation to the enabled? set operation to TRUE .