\begindata{text,538511608} \textdsversion{12} \template{default} \define{global } \bold{\bigger{\bigger{\center{Tutorial on ADEW The Andrew Development Environment Workbench }}}} \italic{\center{For Adew version 5.0 }\center{Release of October, 1991} \center{\italic{Thomas Neuendorffer Information Technology Center Carnegie Mellon University 5000 Forbes Ave. Pittsburgh, Pa. 15213 (412) 268-6108 tpn@andrew.cmu.edu}} }The best way to learn about software is to play with it, and the purpose of this tutorial is to guide your play. The tutorial moves from simple, basic concepts to more complex designs, finishing with a complete step-by-step example of a program that anyone (even a non-programmer!) can create. Because later sections depend on information presented earlier, try and follow the steps in order. Within each section, though, you are encouraged to do some experimenting. This document assumes that you have passing familiarity with some ATK applications, like EZ and Fad, and (more importantly) have read the ADEW Overview file. If you read the Overview file, but did not completely understand it, working through this tutorial will help make some of the concepts presented there more concrete. It is a good idea to read back through the Overview when you come to convenient stopping places in this tutorial. If you want, you can also read through the Reference Manual when you take a break. The important thing at this point is to get started: bring up the Arbcon, fiddle with the switches, create a window and see what it does. You might even have fun! Note on release of Adew 5.0. Adew has had many new features added since this tutorial was written. In order to keep this document as simple as possible, no attempt has been made to cover them all. The interested user is referred to the overview and to the reference manual for further information. Enjoy. \begindata{bp,538269640} \enddata{bp,538269640} \view{bpv,538269640,1411,0,0} \chapter{1 Creating Multi-Object Files} \section{1.1 Getting started} For the benefit of some of the later examples, you might want to create an empty directory in which to do this Tutorial; it will make it easier to create sample applications later on. ADEW applications are created with a program called Arbcon. Arbcon, move into the empty directory you created and type To run \bold{\leftindent{arb}} Once you have an Arbcon window up, you will want to bring up a work area to try some of the examples. To do this, choose \bold{New Window} from the \italic{Arbcon} menu within the Arbcon window. You are prompted for a file name in the message line. Enter a name (like "scratch") and press Enter. The window that appears has a text object in it, by default. You can change what type of object appears in new windows by clicking in the \italic{Object <View>} panel before opening the window. Try that now by clicking on "lset." You should see the following in your Arbcon window: \bold{\leftindent{Copying new lset object}} This lets you know that Arbcon Now choose \bold{New Window}. The specifies that the default object in the by entering a filename, and press window and an lset window. (The lset is copying something into the cutbuffer. filename prompt in the message line window will be lset. Enter. Complete the prompt Now you have two windows, a text window is completely dark.) The \bold{New Window} option can be used to bring up existing files as well as creating new ones. All of the standard commands for reading and saving files which are normally available from EZ are operational, though sometimes it may be necessary to click into an object to bring up the menus. If at any time you have to quit but don't want to lose what you have done, use the \bold{Save All} menu option in one of the new windows you have brought up to save the files you have created, as you would any normal text file. \section{1.2 Working with lset} Lset lets you split a window up into rectangular regions of any size. To do this, choose \bold{Split Horizontal} or \bold{Split Vertically} from the \italic{lset} menu. This gives you a split cursor. The next mouse hit in the lset will split it, creating one light region and one dark region. The dark region is the one that is selected and will be split if you chose a \bold{Split} command again. To change which rectangle is selected, click in a different rectangle. Try splitting the window several different ways to create a bunch of rectangles. The divisions between the rectangles may be moved by dragging on a division. Divisions may also be unsplit via the \bold{Unsplit lset} menu option. Try moving the divisions, and unsplitting one or two divisions. \section{1.3 Adding objects} The basic notion behind using Arbcon is selecting an Object (that Arbcon copies into the cut buffer) and then pasting the object where you would like it to go. In this section you can learn about pasting non-value objects. (In part two of the tutorial, you can learn about value-objects.) Try pasting a Fad object into an lset rectangle. First, click on "fad" in the Arbcon window. You should see the following in the Arbcon window: \leftindent{\bold{Copying new fad object}} Next, move to the lset window, click in the rectangle you want the Fad object to be in, and choose \bold{Paste} from the lset menu. Two things happen. One: in your lset window, there is now a Fad object. Just click in Fad once to give it the input focus (i.e. tell it that it is the thing you want to take commands) and then just click and drag to draw lines. Draw a few things in the Fad object. Two: in your Arbcon window, you should see the following line: \leftindent{\bold{fad-fadview Inset. Name} fad} You do not need to do anything to this line. Just notice that initially you were told that Arbcon was copying a new Fad object. Now, Arbcon is displaying information about the object. You will learn more about this line, and lines like it later in the Tutorial. Now, try pasting a Fad object into the \italic{text} window. Click on "fad" again, see that it is being copied into the cutbuffer, position the text caret in the text window, and choose \bold{Paste} from the front menu in the text window. You need to click in the Fad object to give it input focus and see where it is. Notice that the Fad in the text expands to a bigger size, while the lset Fad won't. This is because text adjusts to its children's size requests, while lset doesn't. This is one of the considerations to take into account when deciding what parent object (in this case, text or lset) to use when creating applications. Try \bold{Pasting} some of the other available objects into your lset or text window. \section{1.4 Naming Objects} Each file you create with Arbcon has associated with it an "arbiter." The arbiters are, by default, named the same as the files they are associated with. You can't change the name of an arbiter. The primary function of an arbiter is to make sure that objects within its file do not have the same name, which would create name conflicts. Specific instances of objects are, by default, named after the object that is in them. Like the name of the first Fad object you create is "fad." You can see the name of an object in the Arbiter window by clicking on it. Notice, that two cels can have the same name if they are in different files, because they have different arbiters. This is the case with the two Fad objects you added to your text and lset files; they are both named "fad." Try Pasting another Fad object into an lset rectangle. Once you choose \bold{Paste}, information about the object (its name) appears: \leftindent{\bold{fad-fadview Inset. Name} fad_1} The object you just added is named "fad_1," to prevent any name conflicts. This is a unique name for the object, and so there is no need to change it. However, if you want to, you can change the name of an object by editing the name as it appears ("fad_1") and pressing the "Save" button at the bottom of the Arbcon window. Try it now. After you have pressed Save, check to see that the name of fad_1 is changed by selecting a different object in the lset window. Then, select the Fad object whose name you just changed. The name should no longer be "fad_1," but what ever you changed it to. Try creating some other objects and changing their names. \section{1.5 The `Scrolled' Switch} In the Arbcon window there is a switch with the labels, "Scrolled" and "Normal." The position of this switch determines whether or not an object is brought up with one or more scroll bars, more generally know in ATK as its "application layer" .(Note: In previous versions of the Arbcon, this was the 'Application' switch, however since all the known ATK views that support this application layer do so by bringing up one or more scroll bars, the button has been renamed accordingly). Try creating a text object in an lset rectangle. rectangle Click in an empty to select it. Then click on "text" in the Arbcon window. Click on "Scrolled" to move the switch. You should see the following in the Arbcon window: \leftindent{\bold{Copying new text object w/ }}scroll bar(s) Move to the lset window and choose \bold{Paste}. Notice how text comes up with a scroll bar. Try creating a Raster object in an lset cel. Raster's application layer contains scroll bars in two dimensions. Some objects, like lset, have no application layer; for them the switch has no effect. \section{1.6 Cutting and Copying } By now, you have probably created a lot of objects and are perhaps are getting overloaded. So lets get rid of some of them. Most parents (like lset or text) provide some method for deleting the objects created under them. In text you can cut them out or even just backspace over objects to destroy them (you will be promoted to see if that is what you really want to do). The Arbcon provides the cut button as a means of destroying a cel and putting a copy of it and its child in the ATK cut buffer. Select one of your objects by clicking in it. Click the cut button in the Arbcon window (the button with the scissors). Poof! The object is gone! But, it's not forgotten. By choosing\bold{ Paste} in any object that supports it, a new copy of the object is created. Multiple copies may be created. Objects may also be moved from one parent to another. The Copy button buffer, without various objects by appending a '-' \section{1.7 in the Arbcon window places a copy of the cel in the cut destroying the original object. Try cutting and copying around. Note that name conflicts are resolved as above, and a unique number to the name to make it unique. Linking Cels} As mentioned in the Overview document, ATK supports the notion of multiple views on a single piece of data. The link button on the Arbcon provides an interface to this feature. Here you can use it to link two Fad views to the same data, so when you draw in one object it will show up in the other. In your lset window, create an empty rectangle. Now, select one of your existing Fad objects in the lset window and click on the link switch in the Arbcon window. Note the following in the message line of Arbcon: \leftindent{Copying new fadview link to fad} By default, the object you want to link to is made the same as the object you want to link from. Now select the empty target rectangle\bold{ }to link to \bold{in the same parent} (links may not extend across arbiters) and choose \bold{Paste}. The new object will be another copy of the Fad object. Notice if you go into the new Fad object and add a new line (or move an old one) that the other Fad object also changes. \subsection{1.7.1 Write-Ins} Occasionally, one may come across an object that you wish to create that is not on the default \italic{Objects <View>} list. When you come across this situation, you can use the \bold{Add Object }option on the \italic{Arbcon} menu card. This prompts you for a new object to add. The syntax is the same as description that appears in the Arbcon window. \begindata{bp,538930120} \enddata{bp,538930120} \view{bpv,538930120,1412,0,0} \chapter{2 The Value Objects } In the previous section you created two Fad views on the same data, or object. In this section, you can learn about creating different views on the same data by using "values." Values are simple dataobjects designed to provide a simple and consistent interface for insets that share a common feature: \leftindent{\italic{They only need to store an integer, string, and/or string array. }} The value views are sliders, thumbwheels, buttons, bargraphs, and other objects that can be combined to create applications. \section{2.1 Creating value objects} In your Arbcon window, choose \bold{Init Value Window}. This will bring up a window that has all the valueview objects in it. Click on each of the objects. Notice how the attributes of the object that is selected appear in the Arbcon window, like the following: \leftindent{\bold{value-onoffV Inset. Name} onoff_0 \bold{\bold{string style string background-color string foreground-color }long bodyfont-size} 10 \bold{string bodyfont} andy \bold{string top label }on-off \bold{string bottom label} switch} Do not worry about the attributes now. when you click on different objects. Simply notice that they change (Notice to select clicklist, menustrV and String Entry you need to click in a specific region within their box.) When you click on an object and its attributes appear in the Arbcon window, it is copied into the cutbuffer, just like for text, lset and Fad in the previous section. You can then \bold{Paste} the object into your text or lset window. Try Pasting a slider. When you click and move the cursor on the slider, its value goes up and down. Paste some other value objects into your text and lset windows. \section{2.2 Editing the valueview's attributes} Unlike text, lset, Fad, and other non-value objects, valueviews have user setable parameters (called attributes) to describe how they will display themselves. More often that not, this will include a label and the font to display it. These may be set via the Arbcon. The attributes look like: \leftindent{\bold{Type-of-field Name of the field} field contents} The "field contents" is the user setable parameter. To set the parameters, just go into that area and type the desired values. For example, \bold{Paste} an on-off switch somewhere. You should see the attributes listed in the Arbcon window like those above. Now, change them to look like the following: \leftindent{\bold{value-onoffV Inset. Name} onoff_0 \bold{\bold{string style string background-color string foreground-color }long bodyfont-size} 12 \bold{string bodyfont }andysans \bold{string top label} ON \bold{string bottom label} OFF} When you are done, click the Save button. The on-off switch should change to reflect its new values and labels. Try creating and editing some of the other valueviews (ignore controlV for the moment). Then try going back to an object already edited, select it, edit it, and change some of the parameters. \section{2.3 Linking Values} As with other objects, value objects may be linked. Since they all use the same data object, valueviews of different types may also be linked. Create a sliderV valueview in your text window and then click the link button. Notice in the message line of the Arbcon window: \leftindent{Copying New sliderV link to slider_0} As with are linking another down and the Fad, the default object to link to is identical to the object you from. Now choose \bold{Paste} in your text window. This Pastes slider that is linked to the first one. Slide one slider up and other one moves, too. Now, click on the first slider and flip the switch to link again. This time, when you see the message in the message line, click on "value bargraphV" in the Arbcon window. The message line should read: \leftindent{Copying New bargraphV link to slider_0} This tells you that a bargraph is being copied into the cut buffer. Note that what is being copied into the cut buffer does not appear in the area of the window that it would normally appear in. All you see is the notification in the message line. Now, \bold{Paste} in your text window again. If all went well, moving the slider should cause the graph to move as well. Note how the graph only changes when you let up the mouse button on the slider. This is because valueviews are 'up sensitive'. What happens when you slide the slider and the move the mouse pointer outside of it? This is the way one can change one's mind about changing the value before it gets changed. Try changing the max and min values of the bargraph. Note how they are not linked to the range of the slider. Try some other combinations of value pairs, like a sliderV and a bargraphV. \section{2.4 EnterstrV} As you may have noticed, enterstrV is a somewhat special value. It is a combination of a button object and a special text object that lets you enter strings. Try creating one. Use the following attributes: \leftindent{\bold{value enterstrV Inset Name} menterstea_0 \bold{string style string background-color string foreground-color }\bold{long bodyfont-size} 10 \bold{string bodyfont} andy \bold{string label} Click to enter value.} Try linking this object to a "stringV" valueview. What happens when a string is entered? Make a third link to a bargraph and enter '50 beans' into the enterstrV. Try other links. \section{2.5 Notes} You may have noticed that some different valueviews seem to act alike (sliderV and sliderstrV, thumbV and thumbstrV). We have also avoided the controlV and menterstrV objects. These are objects whose special qualities show up when creating applications. For now, suffice it to say that the thumbstr and sliderstr objects can be used to display string arrays instead of numbers (the Objects and Views wheels are thumbstrVs); the controlV can be used to directly call a function; and menterstrV stands for multiple-enter-strings, and can be used to prompt the user for several parameters at once. This ends part 2 of the tutorial. At this point you should know about all there is to know about constructing text and lset files with the Arbcon. As mentioned, the Arbcon was designed to work with any ATK parent object, though it has been mostly tested in text and lset. If you are familiar with Zip or Table, try using Arbcon with them (See the note in the Cut section, however.) If you are unclear about any of the above operations, go back and review that area. You also might want to re-read the Overview again at this point. One last thing to try, if you haven't already, is objects within objects. The Arbcon is not limited to one level. Try creating a text object in an lset rectangle, then create an lset within that text, and so on. \begindata{bp,539690184} \enddata{bp,539690184} \view{bpv,539690184,1413,0,0} \chapter{3 Creating Controllers} \section{3.1 Controller Options } Creating files of buttons and switches is all well and fine, but what can you \italic{do} with them? Atk currently provides two options for binding together sets of objects into applications. \subsection{3.1.1 Createcon }The first option, createcon, is described below. It requires some knowledge of the C programming language (including knowledge of structures, pointers, and function calls), but knowledge of ATK programming is not required. Tools are provided to greatly simplify the process of creating a dynamically loaded controller program using C and the Atk class preprocessor. The tutorial below demonstrates how a simple application can be created with one line of user written C code. \subsection{3.1.2 Ness }An alternative is provided by the interpreted language Ness. Ness is particularly suited to string-processing applications, and for creating applications that embed the controller information in the document itself, rather than in a separately loaded module. Readers who are unfamiliar with C or who prefer to work in an interpreted environment may wish to forego the following and instead refer to the NESS documentation for further information on how to create applications with NESS. \section{3.2 A digital analog computer example.} Remember analog computers, like the one you may have made for the science fair as a kid? With two big dials or slider switches with numbers, and a meter? You could set the dials to a numbers and the meter would show you their sum. This part of the Tutorial takes you through how to use the ADEW tools to make a digital analog computer (or, to be precise, a digital computer analog of an analog computer :). Teaching is by example. If you haven't gone through the Tutorial Parts 1 and 2, please do so before continuing. \subsection{3.2.1 Setting up} The following will walk you through the creation of a dynamic object. Before you begin there is one important step. By default, EZ will only load dynamic objects from the system directory. You have to tell it to load objects from one of your own directories if that is what you plan to do (and it is). To set this up place the following in your ~/.cshrc: if ($?CLASSPATH) then setenv CLASSPATH $\{CLASSPATH\}:. else if ($?ANDREWDIR) then setenv CLASSPATH $\{ANDREWDIR\}/dlib/atk:. else setenv CLASSPATH /usr/andrew/dlib/atk:. setenv ANDREWDIR /usr/andrew endif Now type "source ~/.cshrc". Since .cshrc is always executed when the cshell starts up, this only has to be done once. (This assumes you run the cshell.) \subsection{3.2.2 Create a new lset object} Create an empty directory (or clear out the directory you used to do the examples above). Start Arbcon and use \bold{New Window} to create an lset object. It doesn't matter what you call the new file. Split the lset into four rectangles and Paste in: 2 sliderVs (named \italic{sl_0} and \italic{sl_1}, min and max of 1 and 100) 1 bargraphV (named \italic{bg}, min and max of 0 and 200) 1 controlV (named \italic{go}) Setting the attributes for the controlV object requires a little explanation. When we go to edit it in the Arbcon, we are presented with some attributes that we have not seen before: Auto-Init, function and class. These attributes allow your application to call functions and actually do things. ATK has what is called a "proctable," which is basically just a list of functions that can be looked up and called by name. ControlV was designed to look up a function from this list and call it when clicked on. You are going to use this controlV object to create a button that will start your calculator. Thus, it should have the following attributes: \bold{value controlV Inset Name} go \bold{\bold{string style }}\indent{Indicates the style of button to display, currently supported are styles 1,2,3, and 4. Different styles can be set for color and monochrome displays. See the reference manual for details}.\bold{\bold{ string background-color string foreground-color }}\indent{Sets the color for the button. }\bold{string Auto-Init} true \indent{This is a boolean flag to indicate if the function should be called once automatically the first time the controlV is drawn. Set this to \italic{true}. NOTE: to make application creation easier, ControlV will only call the function automatically if the Arbcon is not present. }\bold{string function} start \leftindent{This name is appended to the class name (with a '-') to produce the proctable function name to look up. }\indent{ }\bold{string class} daccon \indent{This is the object to load where the function is expected to be defined. For ADEW application, this is where you should specify the name for the controller you wish to create. Call it \italic{daccon}, for digitalanalog computer controller. }\bold{long bodyfont-size} 12 \bold{string bodyfont} andy \bold{string label} Go At this point your window should look something like this: \center{\ \begindata{raster,539699336} 2 0 68266 68266 0 0 442 288 bits 539699336 442 288 ZZUc0 | ZZUc0 | c0zztc0 | c0zztc0 | c0t15/55/55#55 ic0 | c7Gc0r2a/aa/aa#aa gGf8c0 | c4g40h06c0hc0 g0cg03g15/55/55#55 g!88c0 | c5c140h06c0hc0 g0cg03g2a/aa/aa#aa g!88c0 | c4e2401e7c05eb b9b0b66c0cf1e7 8015/55/55#55 c4e44033!0ccc cdd9bb760d9b33 g2a/aa/aa#aag c4744033180ccc cd99b3660dc333 g15/55/55#55g c428403f1008cc cd9933660c73f3 g2a/aa/aa#aag c45c40!3008cc cd9933660c3b03 g15/55/55#55g c49c40336018dc cddb33666d9b33 402a/aa/aa#aa c48e401e7c186c cdb333666cf1e1 8015/55/55#55 c50740j0180l2a /aa/aa#aag8008 c0 | c4g40j0180l15 /55/55#55g8008 c0 | c7Gc0j0180l2a /aa/aa#aagGf8 c0 | c0t15/55/55#55 ic0 | c0zztc0 | c0zztc0 | ZZUc0 | ZZUc0 | ZZUc0 | e0zj01c0s1cs01 c0 | e0zj01c0s1cs01 c0 | e0zj01c0s1cs01 c0 | e0zj01c0s1cs01 c0 | e0zj01c0s1cs01 c0 | e0zj01c0s1cs01 c0 | e0zj01c0s1cs01 c0 | e0zj01c0s1cs01 c0 | e0rc0q01c0l60 l1cl06l01c0 | e0q0120q01c0l 90l1cl09l01c0 | e0q0120q01c0l 90l1cl09l01c0 | e0q0120q01c0l 90l1cl09l01c0 | e0q0120q01c0l 90l1cl09l01c0 | e0q0120q01c0l 90l1cl09l01c0 | e0rc0q01c0l60 l1cl06l01c0 | e0zj01c0s1cs01 c0 | e0zj01c0k!5550 k1ck05!55k01c0 | e0zj01c0k!aaa0 k1ck0a!aak01c0 | e0zj01c0k4888 80k1ck04!88k01 c0 | g!88c0 | f888c0 | 8088c0 | 8088c0 | 8088c0 | gG88c0 | g8008c0 | e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 c0 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0p2a"aa80o01 e0p#5540o01c0 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 c0ka22220k1ck k488880k1ck04 c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | c0 | 0a!22k01c0 | !88k01c0 | e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 e0zj01c0k4888 e0zj01c0ka222 ZLc0k488880k1c ZLc0ka222l1ck e0zj01c0k4888 e2/22'2223c0k e0/88'888dc0k ea/22'2223c0k e0/88'888dc0k e2/22'2223c0k e0/88'888dc0k ea/22'2223c0k e0/88'888dc0k e2/22'2223c0k e0/88'888dc0k ea/22'2223c0k e0/88'888dc0k e2/22'2223c0k e0/88'888dc0k ea/22'2223c0k e0/88'888dc0k e2/22'2223c0k e0*88bd08*888d ea*2263+2223c0 e0*88c908*888d e2*22832e*2223 e0+881b08)888d ea*22a7b1*2223 e0*88891108)88 e2*22c333*2223 e0*886b1b08)88 ea*223e2e*2223 e0*88!80*888d e2/22'2223c0k e0/88'888dc0k ea/22'2223c0k e0/88'888dc0k e2/22'2223c0k e0/88'888dc0k ea/22'2223c0k e0/88'888dc0k e2/22'2223c0k e0/88'888dc0k ea/22'2223c0k e0/88'888dc0k e2/22'2223c0k e0/88'888dc0s ea/22'2223c0s e0/88'888dc0s l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 80k1ck04!88k01 l1ck0a2220k01 80k1ck04!88k01 20k1ck0a!22k01 k04!88k01c0 | 0a2220k01c0 | 80k1ck04!88k01 a22220k1ck0a!22 488880k1ck04!88 a222l1ck0a2220 488880k1ck04!88 a22220k1ck0a!22 488880k1ck04!88 a222l1ck0a2220 488880k1ck04!88 a22220k1ck0a!22 488880k1ck04!88 a222l1ck0a2220 488880k1ck04!88 a22220k1ck0a!22 488880k1ck04!88 a222l1ck0a2220 488880k1ck04!88 a22220k1ck0a!22 c0k488880k1ck ka222l1ck0a22 c0k488880k1ck c0ka22220k1ck c0k488880k1ck c0ka222l1ck0a 8dc0k40m1ck04 c0ka22220k1ck 8dc0k488840k1c c0k822280k1ck c0k488840k1ck a222a0k1ck0a22 488840k1ck0488 822280k1ck0822 488840k1ck0488 a222a0k1ck0a22 488840k1ck0488 822280k1ck0822 488840k1ck0488 a222a0k1ck0a22 455540k1ck0455 8aaa80k1ck08aa 40m1ck04m01c0 | a22220k1ck0a!22 1cs01c0 | 1cs01c0 | 1cs01c0 | c0 c0 c0 c0 c0 c0 c0 | | | | | | | c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | k01c0 | 04!88k01c0 | 20k01c0 | 04!88k01c0 | 0a!22k01c0 | 04!88k01c0 | 2220k01c0 | m01c0 | 0a!22k01c0 | k048884k01c0 | 082228k01c0 | 048884k01c0 | 2ak01c0 | 84k01c0 | 28k01c0 | 84k01c0 | 2ak01c0 | 84k01c0 | 28k01c0 | 84k01c0 | 2ak01c0 | 54k01c0 | a8k01c0 | k01c0 | e2/22'2223c0s 1cs01c0 | e5/55(55c0s1c s01c0 | ea/aa'aaabc0s 1cs01c0 | e0zj01c0s1cs01 c0 | ZZUc0 | ZZUc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | c0zztc0 | ZZUc0 | ZZUc0 | \enddata{raster, 539699336} \view{rasterview,539699336,1414,0,0}} \subsection{3.2.3 Creating the application code } If all looks good, save the file from the lset window as \italic{adc}, and either choose the create controller option from the ADEW menus, or enter the command window and type \leftindent{\bold{createcon adc}} The output from this program will be as follows: \leftindent{Creating a controller for adc. Please wait... running /usr/andy//lib/arbiters/conpros.awk adc Creating daccon.ch Creating daccon.c Creating Imakefile Creating makedaccon shellscript Done } This indicates the new files created. Take a brief look at the generated .c file (appendix 1). At first glance, it will appear rather complex. In fact, it \bold{is} rather complex. However, take heart in the fact that Createcon has taken care of most all of the complexity for you. You will have to edit this code slightly, but you can safely ignore most of it. \subsection{3.2.4 What these file have} What Createcon has done is produce code for a dynamically loadable object that contains: 1. A proctable entry for an initialization function that is keyed to the controlV button. 2. A structure containing pointers to all of the dataobjects and views within the application. The dataobject pointers will be named the same as the object ('-' and other strange characters are translated to '_'s), the view pointers will be the same, with the addition of the word view. 3. CallBack procedures set up to be called whenever a value stored in one of the value objects changes. These procedures are keyed to the names we gave the objects. A procedure name is the word CallBack appended to the object name. 4. All the files necessary for compiling a dynamic object. Some feature of the Createcon produced code are: 1. If several values have the same name, differing only by a -<number>. Only one call back procedure will be set up for all of them. The third argument to the function (r1) will be set to the -<number> of the calling value. 2. The code contains many comments of the form /* user code begins here for foo */ /* user code ends here for foo */ It is between the comments that all user written code should be added. The Createcon program uses these comment to determine what code it should preserve when creating new versions of the code. Thus, if you went back to adc and added a new button. The next running of Createcon will move the old c code to a backup file and merge in the additions you made into the new code. 3. A .ch file, containing the class definition is also created. It also contains comments, as in 2. above, where the applications programmer may add additional fields to the structure he will always be passed in the callback routines. \subsection{3.2.5 Adding your code} The next step is to edit daccon.c to produce the desired effect, in this case, cause the bargraph to display the sum of the two sliders. Since you want to be sensitive to any change in the sliders, and we named the sliders sl_0 and sl_1, we need to find slCallBack. It currently looks like this: static void slCallBack(self,val,r1,r2) struct daccon *self; struct value *val; long r1,r2; \{ if(r2 == value_OBJECTDESTROYED) \{ if(self->sl_0 == val) self->sl_0 = NULL; if(self->sl_1 == val) self->sl_1 = NULL; \} \{ /* user code begins here for slCallBack */ /* user code ends here for slCallBack */ \} \} Self points to the controller object, with pointers to all of the child objects. Val is a pointer to the value object that changed. r1 is a pointer to the index of the calling object (either 0 or 1 in this case for sl_0 and sl_1). r2 is either a constant that may be ignored, or the constant value_OBJECTDESTROYED to indicate that the value object has been destroyed. As seen above, createcon generates code to look for this constant and set the pointers to NULL if the objects are destroyed. To get and set the values, it is necessary to know the programmer interface to the value objects. This is detailed in the ADEW Reference manual. There are only about 9 methods (i.e. functions), of which we currently need two: value_GetValue(val) returns the long contents of a value. value_SetValue(val,rock) sets the contents of a value. So our code will be functionally be: \italic{/* user code begins here for slCallBack */} int a,b,c ; a = value_GetValue(self->sl_0); b = value_GetValue(self->sl_1); c = a + b; value_SetValue(self->bg,c); \italic{/* user code ends here for slCallBack */} This, using value_GetValue and value_SetValue, would look like the following: \italic{/* user code begins here for slCallBack */} value_SetValue(self->bg,value_GetValue(self->sl_0) + value_GetValue(self->sl_1)); \italic{/* user code ends here for slCallBack */} This is what you should put in as your code. ATK application written with one line of code. And that is it. A complete To be safe, it is good programming practice to ensure that both objects exist before calling their methods. So the best way to write this code would be: \italic{/* user code begins here for slCallBack */} if(self->sl_0 != NULL && self->sl_1 != NULL) value_SetValue(self->bg,value_GetValue(self->sl_0) + value_GetValue(self->sl_1)); \italic{/* user code ends here for slCallBack */} \section{3.3 Completing the application} Now that you have edited daccon.c, it may be compiled by running the makedaccon shellscript. \bold{\leftindent{makedaccon}} This will produce something like the following output, depending on your machine type and local configuration: ##### Generating Makefile with Relative Path: ./../../../andy making dependencies ./../../../andy/config/depend.csh /usr/local/bin/makedepend /usr/amos //usr/include/X11 "hc" /usr/amos/bin/class "-I. -I/usr/amos/include/atk -I/usr/amos/include -I//usr/include/X11" /usr/amos/bin/class -s -I. -I. I/usr/amos/include -I//usr/include/X11 daccon.ch -I/usr/amos/include/atk - Adding new delimiting line "##### DEPENDENCY LINE - DO NOT DELETE #####" Adding dependencies... rm -f daccon.o cc -c -I. -g -I/usr/amos/include/atk -I/usr/amos/include I//usr/include/X11 daccon.c w "daccon.c",L85/C16: self: Variable is set but is never referenced. <Note: don't worry about warnings of unused variables that some compilers display> /usr/amos/bin/makedo -g -d /usr/amos/lib -b /usr/amos/bin -o daccon.do daccon.o doindex: indexing daccon.do ...OK The first part of this output (up through the \italic{Appending...} line) is the result of the shell scripts use of the \bold{genmake} program to create a new makefile. This should only occur the first time you run makedaccon. Subsequent runs will use the Makefile that this run created. If all goes well the result will be a .do file, which is the dynamic module that is loaded into the EZ editor to make the adc work. Now go back and run \bold{\indent{ez adc}} Slide the controllers and watch it work. \subsection{3.3.1 Trouble Shooting} If it doesn't work, try checking the following. 1. Is the CLASSPATH set? Type printenv CLASSPATH and see if it includes the current directory. above. If not, see Setting Up 2. Did the daccon.do file get produced 3. Did you remember to save the change back into daccon.c \subsection{3.3.2 Note} An interesting side effect of running applications within the Ez editor is the fact that the editor may think that it needs to tell the user quitting the application that the file has changed and needs saving. To prevent this, you can add the following 'magic' line to the start function. arbiterview_SetIgnoreUpdates(v,TRUE); so that the code will read daccon_start(v,dat) struct view *v; long dat; \{ struct daccon *self; if((self = FindSelf(v)) == NULL) return; /* user code begins here for daccon_start */ arbiterview_SetIgnoreUpdates(v,TRUE); /* user code ends here for daccon_start */ \} \subsection{3.3.3 New Features } In responce to user feedback, some new features have been added to Adew. These include the ability to create applications without control buttons and run them outside of the ez editor environment. It is also possible to use the page object create panels that switch between different sets of objects under application control. For details on these and other advanced features, please see the Adew Reference Manual. \subsection{3.3.4 Modifying the application } As mentioned above, createcon will preserve user written code across different versions of the appication. To try this, go back to adc and add another slider whose value should be subtracted from the total of the other two. Then run createcon again and modify the call back. Adew was designed to make this sort of updating as easy as possible. \begindata{bp,539671752} \enddata{bp,539671752} \view{bpv,539671752,1415,0,0} \chapter{4 Epilogue } This is the basic scheme behind creating ADEW applications. Now that this one is working, try adding a switch to indicate to add or multiply. Then think about how these tools might be useful to some application you've been thinking about. A prototype perhaps. Remember, applications are not limited to calls on value objects. Since you have the pointer to all the objects, any of their methods and class procedures are available. The text and simpletext methods for manipulating documents have proven particularly useful. See the ATK documentation for a description of these and others. To see more advanced applications, look in the ATK controllers directory. These demo applications have been installed in $ANDREWDIR/lib/arbiters and may be run as follows ez $ANDREWDIR/lib/arbiters/calc.lset This is a simple calculator and probably the best source code to look at for information on creating more complex applications. ez $ANDREWDIR/lib/arbiters/helparb This is a prototype help application that scans the /usr/andrew/help directory and provides help. ez $ANDREWDIR/lib/arbiters/piano.lset If you are running on an IBM RT or 6152, this piano inset will allow you to play music. It has the distinction of being the first piano ever known to be sent in a completely functional via electronic mail. (it can be viewed, run, and played in the messages program itself). Enjoy. \begindata{bp,539671048} \enddata{bp,539671048} \view{bpv,539671048,1416,0,0} \section{4.1 Appendix 1 } \subsection{4.1.1 daccon.c } <annotations added in angled brackets> /* user code begins here for HeaderInfo */ < This is a good place for Copyright notices and the like > /* user code ends here for HeaderInfo */ #include <andrewos.h> #include <class.h> #include <proctbl.ih> #include <view.ih> #include <arbiterv.ih> #include <daccon.eh> #include <sliderv.ih> #include <bargrphv.ih> #include <celv.ih> #include <value.ih> #include <cel.ih> #include <controlv.ih> /* user code begins here for includes */ <additional includes may be placed here, along with global definitions and static functions> /* user code ends here for includes */ static struct daccon *firstdaccon; static struct daccon *FindSelf(v) struct view *v; \{ struct daccon *self,*last = NULL; struct arbiterview *arbv =arbiterview_FindArb(v); for(self= firstdaccon; self != NULL; self = self->next)\{ if(self->arbv == arbv) return self; last = self; \} self = daccon_New(); self->arbv = arbv; initself(self,v); if(last == NULL) firstdaccon = self; else last->next = self; arbiterview_AddObserver(self->arbv,self); return self; \} static void slCallBack(self,val,r1,r2) struct daccon *self; struct value *val; long r1,r2; \{ if(r2 == value_OBJECTDESTROYED) \{ if(self->sl_0 == val) self->sl_0 = NULL; if(self->sl_1 == val) self->sl_1 = NULL; \} \{ /* user code begins here for slCallBack */ <slider call back. See above for details> /* user code ends here for slCallBack */ \} \} static void bgCallBack(self,val,r1,r2) struct daccon *self; struct value *val; long r1,r2; \{ if(r2 == value_OBJECTDESTROYED) \{ if(self->bg == val) self->bg = NULL; \} \{ /* user code begins here for bgCallBack */ < callback for the bargraph. This application ignores it > /* user code ends here for bgCallBack */ \} \} static initself(self,v) struct daccon *self; struct view *v; \{ < this is where initialization happens > self->v = v; self->bgView = (struct bargraphV *)arbiterview_GetNamedView(v,"bg"); self->bg = (struct value *)arbiterview_GetNamedObject(v,"bg"); if(self->bg) value_AddCallBackObserver(self->bg, self,bgCallBack,0); if(self->bgView) bargraphV_AddObserver(self->bgView,self); self->sl_0View = (struct sliderV *)arbiterview_GetNamedView(v,"sl_0"); self->sl_0 = (struct value *)arbiterview_GetNamedObject(v,"sl_0"); if(self->sl_0) value_AddCallBackObserver(self->sl_0, self,slCallBack,0); if(self->sl_0View) sliderV_AddObserver(self->sl_0View,self); self->sl_1View = (struct sliderV *)arbiterview_GetNamedView(v,"sl_1"); self->sl_1 = (struct value *)arbiterview_GetNamedObject(v,"sl_1"); if(self->sl_1) value_AddCallBackObserver(self->sl_1, self,slCallBack,1); if(self->sl_1View) sliderV_AddObserver(self->sl_1View,self); \} daccon_start(v,dat) struct view *v; long dat; \{ struct daccon *self; if((self = FindSelf(v)) == NULL) return; /* user code begins here for daccon_start */ <This is the place for any code to be called whenever the start button is clicked The findself routine above is responsible for finding the self structure and insuring that the initialization code is run once for each arbiter or file > /* user code ends here for daccon_start */ \} void daccon__ObservedChanged(self,observed,status) struct daccon *self; struct observable * observed; long status; \{ /* user code begins here for ObservedChanged */ < User code that needs to be informed when objects other than the values change should be placed here > /* user code ends here for ObservedChanged */ if(observed == (struct observable *) self->arbv)\{ if (status == observable_OBJECTDESTROYED) self->arbv = NULL; else initself(self,self->v); \} if (status == observable_OBJECTDESTROYED) \{ if (observed == (struct observable *) self->bgView) self>bgView=NULL; if (observed == (struct observable *) self->sl_0View) self>sl_0View=NULL; if (observed == (struct observable *) self->sl_1View) self>sl_1View=NULL; \} \} boolean daccon__InitializeClass(ClassID) struct classheader *ClassID; \{ struct classinfo *viewtype = class_Load("view"); firstdaccon = NULL; proctable_DefineProc("daccon-start",daccon_start, viewtype,NULL,"daccon start"); /* user code begins here for InitializeClass */ < This is the place for code to be run once when the application is loaded, but before any of the pointers are initialized > /* user code ends here for InitializeClass */ return TRUE; \} void daccon__FinalizeObject(ClassID,self) struct classheader *ClassID; struct daccon *self; \{ if(self->bg) value_RemoveCallBackObserver(self->bg, self); if(self->sl_0) value_RemoveCallBackObserver(self->sl_0, self); if(self->sl_1) value_RemoveCallBackObserver(self->sl_1, self); /* user code begins here for FinalizeObject */ < This code is called when the daccon is destroyed. In practice, this is unlikely to happen in the current atk. > /* user code ends here for FinalizeObject */ \} boolean daccon__InitializeObject(ClassID,self) struct classheader *ClassID; struct daccon *self; \{ self->bg = NULL; self->bgView = NULL; self->sl_0 = NULL; self->sl_0View = NULL; self->sl_1 = NULL; self->sl_1View = NULL; self->v = NULL; self->next = NULL; /* user code begins here for InitializeObject */ < If one plans to add other fields to the daccon structure, this is where they should be initialized> < They will need to be declared in daccon.ch (see below) > /* user code ends here for InitializeObject */ return TRUE;\} /* user code begins here for Other Functions */ /* user code ends here for Other Functions */ <if, by virtue of the user changing the source file, a value object gets its name changed so that Createcon no longer has a place to insert old code. It will add an #ifdef UNUSED_CODE and place it at the bottom > \begindata{bp,539670984} \enddata{bp,539670984} \view{bpv,539670984,1417,0,0} \section{4.2 Appendix 2} \subsection{4.2.1 daccon.ch} <annotations added in angled brackets> /* user code begins here for HeaderInfo */ /* user code ends here for HeaderInfo */ class daccon : observable [observe] \{ classprocedures : InitializeClass() returns boolean; FinalizeObject(struct daccon *self); InitializeObject(struct daccon *self) returns boolean; /* user code begins here for classprocedures */ <advanced ATK programmers may wish to define exported methods and /* user code ends here for classprocedures */ overrides: ObservedChanged( struct observable * observed, long status ); user code begins here for overrides */ /* /* user code ends here for overrides */ data: struct value *bg; struct bargraphV *bgView; struct value *sl_0; struct sliderV *sl_0View; struct value *sl_1; struct sliderV *sl_1View; /* user code begins here for classdata */ <This is where additional user parameters may be defined. The end result is that they will be available as struct pointers in the daccon array. Also see the reference manual for information on Adew support for permanant object data.> /* user code ends here for classdata */ struct view *v; struct arbiterview *arbv; struct daccon *next; \}; \begindata{bp,537558784} \enddata{bp,537558784} \view{bpv,537558784,1419,0,0} Copyright 1992 Carnegie Mellon University and IBM. All rights reserved. \smaller{\smaller{$Disclaimer: Permission to use, copy, modify, and distribute this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice, this permission notice, and the following disclaimer appear in supporting documentation, and that the names of IBM, Carnegie Mellon University, and other copyright holders, not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. IBM, CARNEGIE MELLON UNIVERSITY, AND THE OTHER COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL IBM, CARNEGIE MELLON UNIVERSITY, OR ANY OTHER COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. $ }}\enddata{text,538511608}