bammi@cwruecmp.UUCP (Jwahar R. Bammi) (03/22/86)
#!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # wind7.prf # wind8.prf # wind9.prf # This archive created: Fri Mar 21 22:40:54 1986 # By: Jwahar R. Bammi () export PATH; PATH=/bin:$PATH echo shar: extracting "'wind7.prf'" '(17805 characters)' if test -f 'wind7.prf' then echo shar: over-writing existing file "'wind7.prf'" fi sed 's/^X//' << \SHAR_EOF > 'wind7.prf' X.!**************************************************************************** X.! X.! ANTIC PUBLISHING INC., COPYRIGHT 1985. REPRINTED BY PERMISSION. X.! X.! ** Professional GEM ** by Tim Oren X.! X.! Proff File by ST enthusiasts at X.! Case Western Reserve University X.! Cleveland, Ohio X.! uucp : decvax!cwruecmp!bammi X.! csnet: bammi@case X.! arpa : bammi%case@csnet-relay X.! compuserve: 71515,155 X.! X.!**************************************************************************** X.! X.! X.!**************************************************************************** X.! X.! Begin Part 7 X.! X.!**************************************************************************** X.! X.PART VII Menu Structures X.SH HAPPY NEW YEAR XThis is article number seven in the ST XPRO GEM series, and the first for 1986. In this installment, XI will be discussing GEM menu structures and how to use them Xin your application. There is also a short Feedback Xresponse section. You will find the download file containing Xthe code for this column in the file GEMCL7.C in DL3 of the XATARI16 SIG (PCS-58). X.SH MENU BASICS XIn ST GEM, the menu consists of a bar Xacross the top of the screen which displays several sub-menu Xtitles. Touching one of the titles causes it to highlight, Xand an associated "drop-down" to be drawn directly below on Xthe screen. This drop-down may be dismissed by moving to Xanother title, or by clicking the mouse off of the drop-down. X.PP XTo make a selection, the mouse is moved over the Xdrop-down. Each valid selection is highlighted when the Xmouse touches it. Clicking the mouse while over one of Xthese selections picks that item. GEM then undraws the Xdrop-down, and sends a message to your application giving the Xobject number of the title bar entry, and the object number Xof the drop-down item which were selected by the user. The Xselected title entry is left highlighted while your code Xprocesses the request. X.SH MENU STRUCTURES XThe data structure which defines a GEM Xmenu is (surprise!) an object tree, just like the dialogs and Xpanels which we have discussed before. However, the Xoperations of the GEM menu manager are quite different from Xthose of the form manager, so the internal design of the menu Xtree has some curious constraints. X.PP XThe best way to understand these constraints is to look Xat an example. The first item in the download is the object Xstructure (only) of the menu tree from the GEM Doodle/Demo Xsample application. X.PP XThe ROOT of a menu tree is sized to fit the entire Xscreen. To satisfy the visual hierarchy principle (see Xarticle #5), the screen is divided into two parts: THE BAR, Xcontaining the menu titles, and THE SCREEN, while contains Xthe drop-downs when they are drawn. Each of these areas is Xdefined by an object of the same name, which are the only two Xobjects linked directly below the ROOT of a menu tree. You Xwill notice an important implication of this structure: The Xmenu titles and their associated drop-downs are stored in Xentirely different subtrees of the menu! X.PP XWhile examining THE BAR in the example listing, you may Xnotice that its OB_HEIGHT is very large (513). In Xhexadecimal this is 0x0201. This defines a height for THE XBAR of one character plus two pixels used for spacing. THE XBAR and its subtree are the only objects which are drawn on Xthe screen in the menu's quiescent state. X.PP XThe only offspring object of THE BAR is THE ACTIVE. This Xobject defines the part of THE BAR which is covered by menu Xtitles. The screen rectangle belonging to THE ACTIVE is used Xby the GEM screen manager when it waits for the mouse to Xenter an active menu title. Notice that THE ACTIVE and its Xoffspring also have OB_HEIGHTs with pixel residues. X.PP XThe actual menu titles are linked left to right in order Xbelow THE ACTIVE. Their OB_Xs and OB_WIDTHs are arranged so Xthat they completely cover THE ACTIVE. Normally, the title Xobjects are typed G_TITLE, a special type which assures that Xthe title bar margins are correctly drawn. X.PP XTHE SCREEN is the parent object of the drop-down boxes Xthemselves. They are linked left to right in an order Xidentical with their titles, so that the menu manager can Xmake the correct correspondence at run-time. The OB_X of Xeach drop-down is set so that it is positioned below its Xtitle on the screen. X.PP XNotice that it is safe to overlap the drop-downs within a Xmenu, since only one of them will be displayed at any time. XThere is one constraint on the boxes however: They must be Xno greater than a quarter screen in total size. This is the Xsize of the off-screen blit buffer which is used by GEM to Xstore the screen contents when the drop-down is drawn. If Xyou exceed this size, not all the screen under the drop-down Xwill be restored, or the ST may crash! X.PP XThe entries within a drop-down are usually G_STRINGs, Xwhich are optimized for drawing speed. The rectangles of Xthese entries must completely cover the drop-down, or the Xentire drop-down will be inverted when the mouse touches an Xuncovered area! Techniques for using objects other than XG_STRINGs are discussed later in this column. X.PP XThe first title and its corresponding drop-down are Xspecial. The title name, by custom, is set to DESK. The Xdrop-down must contain exactly eight G_STRING objects. The Xfirst (again by custom) is the INFO entry, which usually Xleads to a dialog displaying author and copyright information Xfor your application. The next is a separator string of Xdashes with the DISABLED flag set. The following six objects Xare dummy strings which GEM fills in with the names of desk Xaccessories when your menu is loaded. X.PP XThe purpose of this description of menu trees is to give Xyou an understanding of what lies "behind the scenes" in the Xnext section, which describes the run-time menu library Xcalls. In practice, the Resource Construction Set provides X"blank menus" which include all of the required elements, and Xit also enforces the constraints on internal structure. You Xonly need to worry about these if you modify the menu tree X"on-the-fly". X.SH USING THE MENU Xonce you have loaded the application's Xresource, you can ask the AES to install your menu. You must Xfirst get the address of the menu tree within the resource Xusing: X.FB rsrc_gaddr() Xrsrc_gaddr(R_TREE, MENUTREE, &ad_menu); X.FE Xassuming that MENUTREE is the name you gave the menu in the XRCS, and that ad_menu is a LONG which will receive the Xaddress. Then you call the AES to establish the menu: X.FB menu_bar() Xmenu_bar(ad_menu, TRUE); X.FE XAt this point, the AES draws your menu bar on the screen and Xanimates it when the user moves the mouse into the title Xarea. X.PP XThe AES indicates that the user has made a menu selection Xby sending your application a message. The message type is XMN_SELECTED, which will be stored in msg[0], the first Xlocation in the message returned by evnt_multi(). X.PP XThe AES also stores the object number of the selected Xmenu's title in msg[3], and the object number of the Xselected menu item in msg[4]. Generally, your application Xwill process menu messages with nested C switch statements. XThe outer switch will have one case for each menu title, and Xthe inner switch statements will have a case for each entry Xwithin the selected menu. (This implies that you must give a Xname to each title and to each menu entry when you create the Xmenu in the RCS.) X.PP XAfter the user has made a menu selection, the AES leaves Xthe title of the chosen menu in reverse video to indicate Xthat your application is busy processing the message. When Xyou done with whatever action is indicated, you need to Xreturn the title to a normal state. This is done with X.FB menu_tnormal() Xmenu_tnormal(ad_menu, msg[3], TRUE); X.FE X.sp 1 X.ce 1 X(Remember that msg[3] is the title's object number.) X.sp 1 XWhen your application is ready to terminate, it should Xdelete its menu bar. Do this with the call: Xmenu_bar(ad_menu, FALSE); X.SH GETTING FANCY XThe techniques above represent the bare Xminimum to handle menus. In most cases, however, you will Xwant your menus to be more "intelligent" in displaying the Xuser's options. For instance, you can prevent many user Xerrors by disabling inappropriate choices, or you can save Xspace on drop-downs by showing only one line for a toggle and Xaltering its text or placing and removing a check mark when Xthe state is changed. This section discusses these and other Xadvanced techniques. X.PP XIt is a truism of user interface design that the best way Xto deal with an error is not to let it happen in the first Xplace. It many cases, you can apply this principle to GEM Xmenus by disabling choices which should not be used. If Xyour application uses a "selection precedes action" type of Xinterface, the type of object selected may give the Xinformation needed to do this. Alternately, the state of Xthe underlying program may render certain menu choices Xillegal. X.PP XGEM provides a call to disable and re-enable menu Xoptions. The call is: X.FB menu_ienable() Xmenu_ienable(ad_menu, ENTRY, FALSE); X.FE Xto disable a selection. The entry will be grayed out when Xit is drawn, and will not invert under the mouse and will not Xbe selected by the user. Substituting TRUE for FALSE Xre-enables the option. ENTRY is the name of the object Xwhich is being affected, as assigned in the RCS. X.PP XNote that menu_ienable() will not normally affect the Xappearance or operation of menu TITLE entries. However, Xthere is an undocumented feature which allows this. If ENTRY Xis replaced by the object number of a title bar entry with Xits top bit set, then the entire associated drop-down will be Xdisabled or re-enabled as requested, and the title's Xappearance will be changed. But, be warned that this feature Xdid not work reliably in some early versions of GEM. Test it Xon your copy of ST GEM, and use it with caution when you Xcannot control the version under which your application may Xrun. X.PP XIt is also possible to disable menu entries by directly Xaltering the DISABLED attribute within the OB_STATE word. XThe routines enab_obj() and disab_obj() in the download show Xhow this is done. They are also used in set_menu(), which Xfollows them immediately. X.PP XSet_menu() is a utility which is useful when you wish to Xsimultaneously enable or disable many entries in the menu Xwhen the program's state changes or a new object is selected Xby the user. It is called with X.FB set_menu() Xset_menu(ad_menu, vector); X.FE Xwhere vector is a pointer to an array of WORDs. The first Xword of the array determines the default state of menu Xentries. If it is TRUE, then set_menu() enables all entries Xin every drop-down of the menu tree, except that the DESK Xdrop-down is unaffected. If it is FALSE, then every menu Xentry is disabled. X.PP XThe following entries in the array are the numbers of Xmenu entries which are to be toggled to the reverse of the Xdefault state. This list is terminated by a zero entry. X.PP XThe advantage of set_menu() is that it allows you to Xbuild a collection of menu state arrays, and associate one Xwith each type of user-selected object, program state, and so Xon. Changing the status of the menu tree may then be Xaccomplished with a single call. X.SH CHECK, PLEASE? XOne type of state indicator which may Xappear within a drop-down is a checkmark next to an entry. XYou can add the checkmark with the call: X.FB menu_icheck() Xmenu_icheck(ad_menu, ENTRY, TRUE); X.FE Xand remove it by replacing the TRUE with FALSE. As above, XENTRY is the name of the menu entry of interest. The Xcheckmark appears inside the left boundary of the entry Xobject, so leave some space for it. X.PP XThe menu_icheck() call is actually changing the state of Xthe CHECKED flag within the entry object's OB_STATE word. If Xnecessary, you may alter the flag directly using do_obj() and Xundo_obj() from the download. X.SH NOW YOU SEE IT, NOW YOU DON'T XYou can also alter the Xtext which appears in a particular menu entry (assuming that Xthe entry is a G_STRING object). The call X.FB menu_text() Xmenu_text(ad_menu, ENTRY, ADDR(text)); X.FE Xwill substitute the null-terminated string pointed to by Xtext for whatever is currently in ENTRY. Remember to make Xthe drop-down wide enough to handle the largest text string Xwhich you may substitute. In the interests of speed, XG_STRINGs drawn within drop-downs are not clipped, so you may Xget garbage characters on the desktop if you do not size the Xdrop-down properly! X.PP XThe menu_text() call actually alters the OB_SPEC field of Xthe menu entry object to point to the string which you Xspecify. Since the menu tree is a static data structure Xwhich may be directly accessed by the AES at any time, be Xsure that the string is also statically allocated and that it Xis not modified without first being delinked from the menu Xtree. Failure to do this may result in random crashes when Xthe user accesses the drop-down! X.SH LUNCH AND DINNER MENUS XSome applications may have such Xa wide range of operations that they need more than one menu Xbar at different times. There is no problem with having Xmore than one menu tree in a resource, but the AES can only Xkeep track of one at a time. Therefore, to switch menus you Xneed to use menu_bar(ad_menu1, FALSE); to release the first Xmenu, then use menu_bar(ad_menu2, TRUE); to load the second Xmenu tree. X.PP XChanging the entire menu is a drastic action. Out of Xconsideration for your user, it should be associated with Xsome equally obvious change in the application which has just Xbeen manually requested. An example might be changing from Xspreadsheet to data graphing mode in a multi-function Xprogram. X.SH DO IT YOURSELF XIn a future column, I will discuss how Xto set up user-defined drawing objects. If you have already Xdiscovered them on your own, you can use them within a Xdrop-down or as a title entry. X.PP XIf the user-defined object is within a drop-down, its Xassociated drawing code will be called once when the Xdrop-down is first drawn. It will then be called in X"state-change" mode when the entry is highlighted (inverted). XThis allows you to use non-standard methods to show Xselection, such as outlines. X.PP XIf you try to insert a user-defined object within the Xmenu title area, remember that the G_TITLE object which you Xare replacing includes part of the dark margin of the bar. XYou will need to experiment with your object drawing code to Xreplicate this effect. X.SH MAKE PRETTY XThere are a number of menu formatting Xconventions which have become standard practice. Using these Xgives your application a recognizable "look-and-feel" and Xhelps users learn it. The following section reviews these Xconventions, and supplies a few hints and tricks to obtain a Xbetter appearance for you menus. X.PP XThe second drop-down is customarily used as the FILE Xmenu. It contains options related to loading and saving the Xfiles used by the application, as well as entries for Xclearing the workspace and terminating the program. X.PP XYou should avoid crowding the menu bar. Leave a couple Xof spaces between each entry, and try not to use more than X70% of the bar. Not only does this look better, but you will Xhave space for longer words if you translate your application Xto a foreign language. X.PP XSimilarly, avoid cluttering menu drop-downs. Try to keep Xthe number of options to no more than ten unless they are Xclearly related, such as colors. Separate off dissimilar Xentries with the standard disabled dashes line. (If you are Xusing set_menu(), remember to consider the separators when Xsetting up the state vectors.) X.PP XIf the number of options grows beyond this bound, it may Xbe time to move them to a dialog box. If so, it is a Xconvention to put three dots following each menu entry which Xleads to a dialog. Also, allow a margin on the menu entries. XTwo leading blanks and a minimum of one trailing blank is Xstandard, and allows room for checkmarks if they are used. X.PP XDangerous menu options should be far away from common Xused entries, and are best separated with dashed lines. Such Xoptions should either lead to a confirming go/no-go alert, or Xshould have associated "undo" options. X.PP XAfter you have finished defining a menu drop-down with Xthe RCS, be sure that its entries cover the entire box. XThen use ctrl-click to select the drop-down itself, and SORT Xthe entries top to bottom. This way the drop-down draws in Xsmoothly top to bottom. X.PP XFinally, it is possible to put entries other than XG_STRINGs into drop-downs. In the RCS, you will need to Ximport them via the clipboard from the Dialog mode. X.PP XSome non-string object, such as icons and images, will Xlook odd when they are inverted under the mouse. There is a Xstandard trick for dealing with this problem. Insert the Xicon or whatever in the drop-down first. Then get a G_IBOX Xobject and position and size it so that it covers the first Xobject as well as the extra area you would like to be Xinverted. X.PP XEdit the G_IBOX to remove its border, and assign the Xentry name to it. Since the menu manager uses objc_find(), Xit will detect and invert this second object when the mouse Xmoves into the drop-down. (To see why, refer to article #5.) XFinally, DO NOT SORT a drop-down which has been set up this Xway! X.SH THAT'S IT FOR NOW! XThe next column will discuss some of Xthe principles of designing GEM interfaces for applications. XThis topic is irreverantly known as GEM mythology or Xinterface religion. The subject for the following column is Xundecided. I am considering mouse and keyboard messages, VDI Xdrawing primitives, and the file selector as topics. Let me Xknow your preferences in the Feedback! X.! X.! X.!***************************************************************************** X.!* * X.!* End Part 7 * X.!* * X.!***************************************************************************** SHAR_EOF if test 17805 -ne "`wc -c 'wind7.prf'`" then echo shar: error transmitting "'wind7.prf'" '(should have been 17805 characters)' fi echo shar: extracting "'wind8.prf'" '(25511 characters)' if test -f 'wind8.prf' then echo shar: over-writing existing file "'wind8.prf'" fi sed 's/^X//' << \SHAR_EOF > 'wind8.prf' X.!**************************************************************************** X.! X.! ANTIC PUBLISHING INC., COPYRIGHT 1985. REPRINTED BY PERMISSION. X.! X.! ** Professional GEM ** by Tim Oren X.! X.! Proff File by ST enthusiasts at X.! Case Western Reserve University X.! Cleveland, Ohio X.! uucp : decvax!cwruecmp!bammi X.! csnet: bammi@case X.! arpa : bammi%case@csnet-relay X.! compuserve: 71515,155 X.! X.!**************************************************************************** X.! X.! X.!**************************************************************************** X.! X.! Begin Part 8 X.! X.!**************************************************************************** X.! X.PART VIII USER INTERFACES X.SH AND NOW FOR SOMETHING COMPLETELY DIFFERENT! XIn response to a Xnumber of requests, this installment of ST PRO GEM will be devoted Xto examining a few of the principles of computer/human interface Xdesign, or "religion" as some would have it. I'm going to start Xwith basic ergonomic laws, and try to draw some conclusions which Xare fairly specific to designing for the ST. If this article Xmeets with general approval, further "homilies" may appear at Xirregular intervals as part of the ST PRO GEM series. X.PP XFor those who did NOT ask for this topic, it seems fair to Xexplain why your diet of hard-core technical information has been Xinterrupted by a sermon! As a motivater, we might consider why Xsome programs are said by reviewers to have a "hot" feel (and Xhence sell well!) while others are "confusing" or "boring". X.PP XAlan Kay has said that "user interface is theatre". I think Xwe may be able to take it further, and suggest that a successful Xprogram works a bit of magic, persuading the user to suspend his Xdisbelief and enter an imaginary world behind the screen, whether Xit is the mathematical world of a spreadsheet, or the land of Pacman Xpursued by ghosts. X.PP XA reader of a novel or science fiction story also suspends Xdisbelief to participate in the work. Bad grammar and clumsy plotting Xby the author are jarring, and break down the illusion. Similarly, Xa programmer who fails to pay attention to making his interface Xfast and consistent will annoy the user, and distract him from Xwhatever care has been lavished on the functional core of the program. X.SH CREDIT WHERE IT'S DUE XBefore launching into the discussion Xof user interface, I should mention that the general treatment and Xmany of the specific research results are drawn from Card, Newell, Xand Moran's landmark book on the topic, which is cited at the end Xof the article. Any errors in interpretation and application to XGEM and the ST are entirely my own, however. X.SH FINGERTIPS XWe'll start right at the user's fingers with the Xbasic equation governing positioning of the mouse, Fitt's Law, Xwhich is given as X.sp 1 X.ce 1 XT = I * LOG2( D / S + .5) X.sp 1 Xwhere T is the amount of time to move to a target, D is the distance Xof the target from the current position, and S is the size of the Xtarget, stated in equivalent units. LOG2 is the base 2 (binary) Xlogarithm function, and I is a proportionality constant, about X100 milliseconds per bit, which corresponds to the human's "clock Xrate" for making incremental movements. X.PP XWe can squeeze an amazing amount of information out of this Xformula when attempting to speed up an interface. Since motion time Xgoes up with distance, we should arrange the screen with the Xusual working area near the center, so the mouse will have to move Xa smaller distance on average from a selected object to a menu or Xpanel. Likewise, any items which are usually used together should Xbe placed together. X.PP XThe most common operations will have the greater impact on Xspeed, so they should be closest to the working area and perhaps Xlarger than other icons or menu entries. If you want to have Xall other operations take about the same time, then the targets Xfarthest from the working area should be larger, and those closer Xmay be proportionately smaller. X.PP XConsider also the implications for dialogs. Small check boxes Xare out. Large buttons which are easy to hit are in. There should Xbe ample space between selectable items to allow for positioning Xerror. Dangerous options should be widely separated from common Xselections. X.SH MUSCLES XAnyone who has used the ST Desktop for any period Xof time has probably noticed that his fingers now know where to find Xthe File menu. This phenomenon is sometimes called "muscle memory", Xand its rate of onset is given by the Power Law of Practice: X.sp 1 X.ce 1 XT(n) = T(1) * n ** (-a) X.sp 1 Xwhere T(n) is the time on the nth trial, T(1) is the time on the Xfirst trial, and a is approximately 0.4. (I have appropriated X** from Fortran as an exponentiation operator, since C lacks one.) X.PP XThis first thing to note about the Power Law is that it only Xworks if a target stays in the same place! This should be a potent Xargument against rearranging icons, menus, or dialogs without some Xexplicit request by the user. The time to hit a target which moves Xaround arbitrarily will always be T(1)! X.PP XIn many cases, the Power Law will also work for sequences of Xoperations to even greater effect. If you are a touch typist, you Xcan observe this effect by comparing how fast you can enter "the" Xin comparison to three random letters. We'll come back shortly Xto consider what we can do to encourage this phenomenon. X.SH EYES XJust as fingers are the way the user sends data to the Xcomputer, so the eyes are his channel from the machine. The rate Xat which information may be passed to the user is determined by Xthe "cycle time" of his visual processor. Experimental results Xshow that this time ranges between 50 and 200 milliseconds. X.PP XEvents separated by 50 milliseconds or less are always Xperceived as a single event. Those separated by more than 200 Xmilliseconds are always seen as separate. We can use these Xfacts in optimizing user of the computer's power when driving the Xinterface. X.PP XSuppose your application's interface contains an icon which Xshould be inverted when the mouse passes over it. We now know Xthat flipping it within one twentieth of a second is necessary Xand sufficient. Therefore, if a "first cut" at the program achieves Xthis performance, there is no need for further optimization, unless Xyou want to interleave other operations. If it falls short, it will Xbe necessary to do some assembly coding to achieve a smooth feel. X.PP XOn the other hand, two actions which you want to appear distinct Xor convey two different pieces of information must be separated Xby an absolute minimum of a fifth of a second, even assuming that Xthey occur in an identical location on which the user's attention Xis already focused. X.PP XWe are able to influence the visual processing rate within the X50 to 200 millisecond range by changing the intensity of the stimulus Xpresented. This can be done with color, by flashing a target, or Xby more subtle enhancements such as bold face type. For instance, Xmost people using GEM soon become accustomed to the "paper white" Xbackground of most windows and dialogs. A dialog which uses a Xreverse color scheme, white letters on black, is visually shocking Xin its starkness, and will immediately draw the user's eyes. X.PP XIt should be quickly added that stimulus enhancement will only Xwork when it unambiguously draws attention to the target. Three or Xfour blinking objects scattered around the screen are confusing, and Xworse than no enhancement at all! X.SH SHORT-TERM MEMORY XBoth the information gathered by the eyes Xand movement commands on their way to the hand pass through short-term Xmemory (also called working memory). The amount of information which Xcan be held in short-term memory at any one time is limited. You can Xdemonstrate this limit on yourself by attempting to type a sheet of Xrandom numbers by looking back and forth from the numbers to the Xscreen. If you are like most people, you will be able to remember Xbetween five and nine numbers at a time. So universal is this Xfinding that it is sometimes called "the magic number seven, plus Xor minus two". X.PP XThis short-term capacity sets a limit on the number of choices Xwhich the user can be expected to grasp at once. It suggests that Xthe number of independent choices in a menu, for instance, should Xbe around seven, and never exceed nine. If this limit is violated, Xthen the user will have to take several glances, with pauses to Xthink, in order to make a choice. X.SH CHUNKING XThe effective capacity of short-term memory can be Xincreased when several related items are mentally grouped as a "chunk". XHumans automatically adopt this strategy to save themselves time. XFor instance, random numbers had to be used instead of text in the Xexample above, because people do not type their native language as Xindividual characters. Instead, they combine the letters into words Xand remember these chunks instead. Put another way, the characters Xare no longer considered as individual choices. X.PP XA well designed interface should promote the use of chunking Xas a strategy by the user. One easy way is to gather together Xrelated options in a single place. This is one reason that like Xcommands are grouped into a single menu which is hidden except for Xits title. If all of the menu options were "in the open", the user Xwould be overwhelmed with dozens of alternatives at once. Instead, a X"Show Info" command, for instance, becomes two chunks: pick File Xmenu, then pick Show. X.PP XSometimes the interface can accomplish the chunking for the user. XConsider the difference between a slider bar in a GEM program, and Xa three digit entry field in a text mode application. Obviously, Xthe GEM user has fewer decisions to make in order to set the associated Xvariable. X.SH THINK! XWhile we are puttering around trying to speed up Xthe keyboard, the mouse, and the screen, the user is actually Xtrying to get some work done. We need to back off now, and Xlook at the ways of thinking, or cognitive processes, that go into Xaccomplishing the job. X.PP XThe user's goal may be to enter and edit a letter, to retrieve Xinformation from a database, or simply draw a picture, but it Xprobably has very little to do with programming. In fact, the XProblem Space Principle says that the task can be described as Xa set of states of knowledge, a set of operators and associated Xconstraints for changing the states, and the knowledge to Xchoose the appropriate operator, which resides in the user's head. X.PP XThose with a background in systems theory can consider this Xas a somewhat abstract, but straightforward, statement in terms of Xstate variables and operators. A programmer might compare the Xknowledge states to the values of variables, the operators to Xarithmetic and logic operations, the constraints to the rules of Xsyntax, and the user's knowledge to the algorithm embodied by a Xprogram. X.SH ARE WE NOT MEN? XA rational person will try to attain his Xgoals (get the job done) by changing the state of his problem space Xfrom its initial state to the goal state. The initial state, Xfor instance, might be a blank word processor screen. The desired Xfinal state is to have a completed business letter on the screen. X.PP XThe Rationality Principle says that the user's behavior in Xtyping, mousing, and so on, can be explained by considering the Xtasks required to achieve the goal, the operators available to Xcarry out the tasks, and the limitations on the user's knowledge, Xobservations, and processing capacity. This sounds like the Xtypical user of a computer program must spend a good deal of time Xscratching his head and wondering what to do next. In fact, one Xof Card and Moran's key results is that this is NOT what takes place. X.PP XWhat happens, in fact, is that the trained user strikes a sort Xof "modus vivendi" with his tool and adopts a set of repetitive, Xtrained behavior patterns as the best way to get the job done. XHe may go so far as to ignore some functions of the program in Xorder to set up a reliable pattern. What we are looking for is a Xway of measuring and predicting the "quality" of this trained Xbehavior. Since using computers is a human endeavor, we should Xconsider not only the speed with which the task is completed, but Xthe degree of annoyance or pleasure associated with the process. X.PP XCard and Moran constructed a series of behavioral models which Xthey called GOMS models, for Goals-Operators-Methods-Selection. XThese models suggested that in the training process the user Xlearned to combine the basic operators in sequences (chunks!) Xwhich then became methods for reaching the goals. Then these Xfirst level methods might be combined again into second level Xmethods, and so forth, as the learning progressed. X.PP XThe GOMS models were tested in a lengthy series of trials Xat Xerox PARC using a variety of word processing software. (Among Xthe subjects of these experiments were the inventors of Xthe windowing methods used in GEM!) The results were again Xsurprising: the level of detail in the models was really unimportant! X.PP XIt turned out to be sufficient to merely count up the number Xof keystrokes, mouse movements, and thought intervals required Xby each task. After summing up all of the tasks, any extra time Xfor the computer to respond, or the user to move his hands from Xkeyboard to mouse, or eyes from screen to printed page is added in. XThis simplified version is called the Keystroke-Level Model. X.PP XAs an example of the Keystroke Model, consider the task of Xchanging a mistyped letter on the screen of a GEM word processor. XThis might be broken down as follows: 1) find the letter on the screen; X2) move hand to mouse; 3) point to letter; 4) click mouse button; X5) move hand to keyboard; 6) strike "Delete" key; 7) strike key Xfor new character. X.PP XThe sufficiency of the Keystroke Model is great news for our Xattempt to design faster interfaces. It says we can concentrate Xour efforts on minimizing the number of total actions to be taken, Xand making sure that each action is as fast as possible. We have Xalready discussed some ways to speed up the mouse and keyboard Xactions, so let's now consider how to speed up the thought intervals, Xand cut the number of actions. X.PP XOne way to cut down "think time" is to make sure that the Xcapacity of short-term memory is not exceeded during the course of Xa task. For example, the fix-a-letter task described above required Xthe user to remember 1) his place in the overall job of typing the Xdocument; 2) the task he is about to perform; 3) where the bad Xcharacter appeared, and 4) what the new character was. When this Xtotal of items creeps toward seven, the user often loses his place Xand commits errors. X.PP XYou can appreciate the ubiquity of this problem by considering Xhow many times you have made mistakes nesting parentheses, Xor had to go back to count them, because too many things happened Xwhile typing the line to remember the nesting levels. The moral is that Xoperations with long strings of operands should be avoided when Xdesigning an interface. X.PP XThe single most important factor in making an interface Xcomfortable to use is increasing its predictability, and Xdecreasing the amount of indecision present at each step during Xa task. There is (inevitably) an Uncertainty Principle which Xrelates the number of choices at each step to the associated Xtime for thought: X.sp 1 X.ce 1 XT = I * LOG2 ( N + 1) X.sp 1 Xwhere LOG2 is the binary logarithm function, N is the number of Xequally probable choices, and I is a constant of approximately X140 msec/bit. When the alternates are not equally probable, the Xfunction is more complex: X.sp 1 X.ce 1 XT = I * SUM-FOR-i-FROM-1-TO-N (P(i) * LOG2( 1 / P(i) + 1) ) X.sp 1 Xwhere the P(i) are the probabilities of each of the choices (which Xmust sum to one). (SUM-FOR-i... is the best I can do for a sigma Xoperator on-line!) Those of you with some information theory Xbackground will recognize this formula as the entropy of Xthe decision; we'll come back to that later. X.PP XSo what can we learn from this hash? It turns out, as we might Xexpect, that we can decrease the decision time by making some Xof the user's choices more probable than others. We do that by Xmeans of feedback cues from the interface. X.PP XThe important of reliable, continuous meaningful feedback Xcannot be emphasized enough. It helps the beginner learn the system, Xand its predictability makes the program comfortable for the expert. XPrograms with no feedback, or unreliable cues, produce confusion, Xdissonance, and frustration in the user. X.PP XThis principle is so important that I going to give several Xexamples from common GEM practice. The Desktop provides several Xinstances. When an object is selected and a menu drops down, only Xthose choices which are legal for the object are in black. The Xothers are dimmed to grey, and are therefore removed from the Xdecision. When a pick is made from the menu, the bar entry remains Xblack until the operation is complete, reassuring the user that Xthe correct choice was made. In both the Desktop and the RCS, Xitems which are double-clicked open up with a "zoom box" from Xthe object, again showing that the right object was picked. X.PP XOther techniques are useful when operator icons are exposed on Xthe screen. When an object is picked, the legal operations might Xbe outlined, or the bad choices might be dimmed. If the screen Xflashing produced by this is objectionable, the legal icons can Xbe made mouse sensitive, so they will "light up" when the cursor Xpasses over - again showing the user which choices are legal. X.PP XThe desire for feedback is so strong that it should be provided Xeven while the computer is doing an operation on its own. The hour Xglass mouse form is a primitive example of this. More sophisticated Xare "progress indicators" such as animated thermometer bars, Xclocks, or text displays of the processing steps. The ST Desktop Xprovides examples in the Format and Disk Copy functions. The purpose Xof all of these is to reassure the user that the operation is Xprogressing normally. Their lack can lead to amusing spectacles Xsuch as secretaries leaning over to hear if their disk drives are Xworking! X.PP XAnother commonly overlooked feature is error prevention and Xcorrection. Card and Moran's results showed that in order to go Xfaster, people will tolerate error rates of up to 30% in their Xwork. Any program which does not give a fast way to fix mistakes Xwill be frustrating indeed! X.PP XThe best way to cope with an error is to "make it didn't happen", Xto quote a common child's phrase. The same feedback methods Xdiscussed above are also effective in preventing the user from Xpicking inappropriate combinations of objects and operations. XReplacement of numeric type-ins with sliders or other visual Xcontrols eliminates the common "Range Error". The use of radio Xbuttons prevents the user from picking incompatible options. XWhen such techniques are used consistently, the beginner also Xgains confidence that he may explore the program without blundering Xinto errors. X.PP XOnce an error has occured, the best solution is to have an X"inverse operation" immediately available. For instance, the way Xto fix a bad character is to hit the backspace key. If a line is Xinadvertantly deleted, there should be a way to restore it. X.PP XSometimes the mechanics of providing true inverses are Ximpractical, or end up cluttering the interface themselves. In Xthese cases, a global "Undo" command should be provided to Xreverse the effect of the last operation, no matter what it was. X.SH OF MODES AND BANDWIDTH XNow I am going to depart from Xthe Card, Newell and Moran thread of discussion to consider Xhow we can minimize the number of operations in a task by Xaltering the modes of the interface. Although "no modes" has Xbeen a watchword of Macintosh developers, the term may need Xdefinition for Atarians. X.PP XSimply stated, a mode exists any time you cannot get to Xall of the capabilities of the program without taking some Xintermediate step. Familiar examples are old-style "menu-driven" Xprograms, in which user must make selections from a number of Xnested menus in order to perform any operation. The options Xof any one menu are unavailable from the others. X.PP XRecall that the user is trying to accomplish work in his Xown problem space, by altering its states. A mode in the Xprogram adds additional states to the problem space, which he is Xforced to consider in order to get the job done. We might call Xan interface which is completely modeless "transparent", because it Xadds no states between the user and his work. One of the best Xexamples of a transparent program is the 15-puzzle in the Macintosh Xdesk accessory set. The problem space of rearranging the tiles Xis identical between the program and a physical puzzle. X.PP XUnfortunately, most programmers find themselves forced to Xput modes of some sort into their programs. These often arise Xdue to technological limitations, such as memory space, screen X"real estate", or performance limitations of peripherals. The Xquestion is how the modes can be made least offensive. X.PP XI will make the general claim that the frustration which a Xmode produces is directly proportional to the amount of the user's Xbandwidth which it consumes. In other words, we need to consider Xhow many keystrokes, mouse clicks, eye movements, and so on, are Xgoing into manipulating the true problem states, and how many Xare being absorbed by the modes of the program. If the interface Xis wasting a large amount of the user's effort, it will be perceived Xas slow and annoying. X.PP XHere we can consider again the hierarchy of goals and methods Xwhich the user employs. When the mode is low in the hierarchy, Xand close to the user's "fingertips", it is encountered the most Xfrequently. For instance, consider how frustrating it would be Xto have to hit a function key before typing in each character! X.PP XThe "menu-driven" style of programs mentioned above are Xalmost as bad, since usually only one piece of information is Xcollected at each menu. Such a program becomes a labyrinth of Xstates better suited to an adventure game! X.PP XThe least offensive modes are found at the higher, goal Xrelated levels of the hierarchy. The better they align with Xchanges in the state of the original problem, the more they Xare tolerated. For example, a word processing program might Xhave one screen layout for program editing, another for writing Xletters, and yet another while printing the documents. A Xmulti-function business package might have one set of menus for Xthe spreadsheet, another for a graphing module, and a third Xfor a database. X.PP XIn some cases the problem solved by the program has convenient X"fracture lines" which can be used to define the modes. An Xexample in my own past is the RCS, where the editing of each Xtype of resource tree forms its own mode, with each of the modes Xnested within the overall mode and problem of composing the Xentire resource tree. X.SH TO DO IS TO BE! XAny narrative description of user interface Xis bound to be lacking. There is no way text can convey the vibrancy Xand tactile pleasure of a good interface, or the sullen boredom Xof a bad one. Therefore, I encourage you to experiment. Get out Xyour favorite arcade game and see if you can spot some of the Xelements I have described. Dig into your slush pile for the most Xannoying program you have ever seen, run it and see if you can see Xmistakes. How would you fix them? Then... go do it to your own Xprogram! X.SH AMEN... XThis concludes the sermon. I'd like some Feedback Xas to whether you found this Boring Beyond Belief or Really Hot XStuff. If enough people are interested, homily number two will Xappear a few episodes from now. The very next installment of ST XPRO GEM will go back to basics to explore VDI drawing primitives. XIn the meantime, you might investigate some of the Good Books on Xinterface design referenced below. X.br X.ne 4 X.bold 1 XREFERENCES X.sp 1 X.in +4 XStuart K. Card, Thomas P. Moran, and Allen XNewell, THE PSYCHOLOGY OF HUMAN-COMPUTER INTERACTION, Lawrence XErlbaum Associates, Hillsdale, New Jersey, 1983. X.br X(Fundamental Xand indispensible. The volume of experimental results make it Xweighty. The Good Parts are at the beginning and end.) X.sp 1 X"Macintosh User Interface Guidelines", in INSIDE MACINTOSH, XApple Computer, Inc., 1984. X.br X(Yes, Atarians, we have something to Xlearn here. Though not everything "translates", this is a fine Xpiece of principled design work. Read and appreciate.) X.sp 1 XJames D. Foley, Victor L. Wallace, and Peggy Chan, "The XHuman Factors of Computer Graphics Interaction Techniques", XIEEE Computer Graphics (CG & A), November 1984, pp. 13-48. X.br X(A good overview, including higher level topics which I have Xpostponed to a later article. Excellent bibliography.) X.sp 1 XJ. D. Foley and A. Van Dam, FUNDAMENTALS OF INTERACTIVE XCOMPUTER GRAPHICS, Addison Wesley, 1984, Chapters 5 and 6. X.br X(If you can't get the article above, read this. If you are designing Xgraphics apps, buy the whole book! Staggering bibliography.) X.sp 1 XBen Schneidermann, "Direct Manipulation: A Step Beyond XProgramming Languages", IEEE Computer, August 1983, pp. 57-69. X.br X(What do Pacman and Visicalc have in common? Schneidermann's Xanalysis is vital to creating hot interfaces.) X.in -4 X.! X.! X.!***************************************************************************** X.!* * X.!* End Part 8 * X.!* * X.!***************************************************************************** SHAR_EOF if test 25511 -ne "`wc -c 'wind8.prf'`" then echo shar: error transmitting "'wind8.prf'" '(should have been 25511 characters)' fi echo shar: extracting "'wind9.prf'" '(21188 characters)' if test -f 'wind9.prf' then echo shar: over-writing existing file "'wind9.prf'" fi sed 's/^X//' << \SHAR_EOF > 'wind9.prf' X.!**************************************************************************** X.! X.! ANTIC PUBLISHING INC., COPYRIGHT 1985. REPRINTED BY PERMISSION. X.! X.! ** Professional GEM ** by Tim Oren X.! X.! Proff File by ST enthusiasts at X.! Case Western Reserve University X.! Cleveland, Ohio X.! uucp : decvax!cwruecmp!bammi X.! csnet: bammi@case X.! arpa : bammi%case@csnet-relay X.! compuserve: 71515,155 X.! X.!**************************************************************************** X.! X.! X.!**************************************************************************** X.! X.! Begin Part 9 X.! X.!**************************************************************************** X.! X.PART IX VDI Graphics: Lines and Solids X.PP XThis issue of ST PRO GEM is the first in a series of two Xwhich will explore the fundamentals of VDI graphics output. In Xthis installment, we will take a look at the commands necessary to Xoutput simple graphics such as lines, squares and circles as well Xas more complex figures such as polygons. The following episode Xwill take a first look at graphics text output, with an emphasis Xon ways to optimize its drawing speed. It will also include Xanother installment of ONLINE Feedback. As usual, there is a Xdownload with this column. You should find it under the name XGEMCL9.C in DL3 of ATARI16 (PCS-58). X.SH A BIT OF HISTORY XOne of the reasons that the VDI can be confusing is that Xdrawing anything at all, even a simple line, can involve setting Xaround four different VDI parameters before making the draw call! X(Given the state of the GEM documents, just FINDING them can be Xfun!) Looking backwards a bit sheds some light on why the VDI is Xstructured this way, and also gives us a framework for organizing Xa discussion of graphics output. X.PP XThe GEM VDI closely follows the so-called GKS standard, which Xdefines capabilities and calling sequences for a standardized Xgraphic input/output system. GKS is itself an evolution from an Xearly system called "Core". Both of these standards were born in Xthe days when pen plotters, vectored graphics displays, and Xminicomputers were the latest items. So, if you wonder why Xsetting the drawing pen color is a separate command, just think Xback a few years when it actually meant what it says! (The Xcynical may choose instead to ponder the benefits of Xstandardization.) X.PP XWhen doing VDI output, it helps if you pretend that the Xdisplay screen really is a plotter or some other separate device, Xwhich has its own internal parameters which you can set up and Xread back. The class of VDI commands called Attribute Functions Xlet you set the parameters. Output Functions cause the "device" Xto actually draw someone once it is configured. The Inquire XFunctions let you read back the parameters if necessary. X.PP XThere are two parameters which are relevant no matter what Xtype of object you are trying to draw. They are the writing mode Xand the clipping rectangle. The writing mode is similar to that Xdiscussed in the column on raster operations. It determines what Xeffect the figure you are drawing will have on data already on the Xscreen. The writing mode is set with the call: X.FB vswr_mode() Xvswr_mode(vdi_handle, mode); X.FE XVdi_handle, here and below, is the handle obtained from Xgraf_handle at the beginning of the program. Mode is a word which Xmay be one of: X.sp 1 X.in +8 X1 - Replace Mode X.br X2 - Transparent Mode X.br X3 - XOR mode X.br X4 - Reverse Transparent Mode X.in -8 X.PP XIn replace mode, whatever is on the screen is overwritten. XIf you are writing characters, this means the background of each Xcharacter cell will be erased. X.PP XIn transparent mode, only the pixels directly under the X"positive" part of the image, that is, where 1-bits are being Xwritten, will be changed. When writing characters, the background Xof the cell will be left intact. X.PP XIn XOR mode, an exclusive or is performed between the screen Xcontents and what is being written. The effect is to reverse the Ximage under areas where a 1-bit occurs. X.PP XReverse transparent is like transparent, but with a "reverse Xcolor scheme". That is, only places where a 0-bit is to be Xput are changed to the current writing color. When you Xwrite characters in reverse transparent (over white), the effect Xis reverse video. X.PP XThe other common parameter is the clipping rectangle. It Xdefines the area on the screen where the VDI is permitted to draw. XAny output which would fall outside of this area is ignored; it is Xeffectively a null operation. The clip rectangle is set with the Xcall: X.FB vs_clip() Xvs_clip(vdi_handle, flag, pxy); X.FE XPxy is a four-word array. Pxy[0] and pxy[1] are the X and Y Xscreen coordinates, respectively, of one corner of your clipping Xrectangle. Pxy[2] and pxy[3] are the coordinates of the Xdiagonally opposite corner of the rectangle. (When working with Xthe AES, use of a GRECT to define the clip is often more Xconvenient. The routine set_clip() in the download does this.) X.PP XFlag is set to TRUE if clipping is to be used. If you set it Xto FALSE, the entire screen is assumed to be fair game. X.PP XNormally, you should walk the rectangle list for the current Xwindow to obtain your clipping rectangles. (See ST PRO GEM #2 for Xmore details.) However, turning off the clip speeds up all output Xoperations, particularly text. You may do this ONLY when you are Xabsolutely certain that the figure you are drawing will not extend Xout of the top-most window, or out of a dialog. X.SH THE LINE FORMS ON THE LEFT XThe VDI line drawing operations include polyline, arc, Xelliptical arc, and rounded rectangle. I'll first look at the XAttribute Functions for line drawing, then go through the drawing Xprimitives themselves. X.PP XThe most common used line attributes are color and width. XThe color is set with: X.FB vsl_color() Xvsl_color(vdi_handle, color); X.FE Xwhere color is one of the standard VDI color indices, ranging Xfrom zero to 15. (As discussed in column #6, the color which Xactually appears will depend on the pallette setting of your ST.) X.PP XThe line width may only be set to ODD positive values, for Xreasons of symmetry. If you try to set an even value, the VDI Xwill take the next lower odd value. The call is: X.FB vsl_width() Xvsl_width(vdi_handle, width); X.FE XThe two less used line parameters are the end style and Xpattern. With the end style you can cause the output line to Xhave rounded ends or arrowhead ends. The call is: X.FB vsl_ends() Xvsl_ends(vdi_handle, begin_style, end_style); X.FE XBegin_style and end_style are each words which may have the Xvalues zero for square ends (the default), one for arrowed ends, Xor two for rounded ends. They determine the styles for the Xstarting and finishing ends of the line, respectively. X.PP XThe line pattern attribute can select dotted or dashed lines Xas well as more complicated patterns. Before continuing, you Xshould note one warning: VDI line output DOES NOT compensate for Xpixel aspect ratio. That is, the dashes on a line will look twice Xas long drawn vertically on a medium-res ST screen as they do when Xdrawn horizontally. The command for setting the pattern is: X.FB vsl_type() Xvsl_type(vdi_handle, style); X.FE XStyle is a word with a value between 1 and 7. The styles Xselected are: X.sp 1 X.in +8 X1 - Solid (the default) X.br X2 - Long Dash X.br X3 - Dot X.br X4 - Dash, Dot X.br X5 - Dash X.br X6 - Dash, Dot, Dot X.br X7 - (User defined style) X.in -8 X.PP XThe user defined style is determined by a 16-bit pattern Xsupplied by the application. A one bit in the pattern turns a Xpixel on, a zero bit leaves it off. The pattern is cycled through Xrepeatedly, using the high bit first. To use a custom style, you Xmust make the call: X.FB vsl_udsty() Xvsl_udsty(vdi_handle, pattern); X.FE Xbefore doing vsl_type(). X.PP XAs I mentioned above, the line type Output Functions Xavailable are polyline, circular and ellliptical arc, and rounded Xrectangle. Each has its own calling sequence. The call for a Xpolyline is: X.FB v_pline() Xv_pline(vdi_handle, points, pxy); X.FE XPoints tells how many vertices will appear on the polyline. For Xinstance, a straight line has two vertices: the end and the Xbeginning. A closed square would have five, with the first and Xlast identical. (There is no requirement that the figure Xdescribed be closed.) X.PP XThe pxy array contains the X and Y raster coordinates for the Xvertices, with a total of 2 * points entries. Pxy[0] and pxy[1] Xare the first X-Y pair, and so on. X.PP XIf you happen to be using the XOR drawing mode, remember that Xdrawing twice at a point is equivalent to no drawing at all. XTherefore, for a figure to appear closed in XOR mode, the final Xstroke should actually stop one pixel short of the origin of the Xfigure. X.PP XYou may notice that in the GEM VDI manual the rounded Xrectangle and arc commands are referred to as GDPs (Generalized XDrawing Primitives). This denotation is historical in nature, and Xhas no effect unless you are writing your own VDI bindings. X.PP XThe rounded rectangle is nice to use for customized buttons Xin windows and dialogs. It gives a "softer" look to the screen Xthan the standard square objects. The drawing command is: X.FB v_rbox() Xv_rbox(vdi_handle, pxy); X.FE XPxy is a four word array giving opposite corners of the Xrectangle, just as for the vs_clip() call. The corner rounding Xoccurs within the confines of this rectangle. Nothing will Xprotrude unless you specify a line thickness greater than one. XThe corner rounding is approximately circular; there is no user Xcontrol over the degree or shape of rounding. X.PP XBoth the arc and elliptical arc commands use a curious method Xof specifying angles. The units are tenths of degrees, so an Xentire circle is 3600 units. The count starts at ninety degrees Xright of vertical, and proceeds counterclockwise. This means that X"3 o'clock" is 0 units, "noon" is 900 units, "9 o'clock" is 1800 Xunits, and 2700 units is at "half-past". 3600 units take you back Xto "3 o'clock". X.PP XThe command for drawing a circular arc is: X.FB v_arc() Xv_arc(vdi_handle, x, y, radius, begin, end); X.FE XX and y specify the raster coordinates of the center of the Xcircle. Radius specifies the distance from center to all points Xon the arc. Begin and end are angles given in units as described Xabove, both with values between 0 and 3600. The drawing of the Xarc ALWAYS proceeds counterclockwise, in the direction of Xincreasing arc number. So values of 0 and 900 for begin and end Xwould draw a quarter circle from "three o'clock" to "noon". XReversing the values would draw the other three quarters of the Xcircle. X.PP XA v_arc() command which specifies a "full turn" is the Xfastest way to draw a complete circle on the screen. Be warned, Xhowever, that the circle drawing algorithm used in the VDI seems Xto have some serious shortcomings at small radii! You can Xexperiment with the CIRCLE primitive in ST Logo, which uses Xv_arc(), to see what I mean. X.PP XNotice that if you want an arc to strike one or more given Xpoints on the screen, then you are in for some trigonometry. If Xyour math is a bit rusty, I highly recommend the book "A XProgrammer's Geometry", by Bowyer and Woodwark, published by XButterworths (London, Boston, Toronto). X.PP XFinally, the elliptical arc is generated with: X.FB v_ellarc() Xv_ellarc(vdi_handle, x, y, xrad, yrad, begin, end); X.FE XX, y, begin, and end are just as before. Xrad and yrad give the Xhorizontal and vertical radii of the defining ellipse. This means Xthat the distance of the arc from center will be yrad pixels at X"noon" and "half-past", and it will be xrad pixels at "3 and 9 Xo'clock". Again, the arc is always drawn counterclockwise. X.PP XThere are a number of approaches to keeping the VDI's Xattributes "in sync" with the actual output operations. Probably Xthe LEAST efficient is to use the Inquire Functions to determine Xthe current attributes. For this reason, I have omitted a Xdiscussion of these calls from this column. X.PP XAnother idea is to keep a local copy of all significant Xattributes, use a test-before-set method to minimize the number of XAttribute Functions which need to be called. This puts a burden Xon the programmer to be sure that the local attribute variables Xare correctly maintained. Failure to do so may result in obscure Xdrawing bugs. If your application employs user defined AES Xobjects, you must be very careful because GEM might call your draw Xcode in the middle of a VDI operation (particularly if the user Xdefined objects are in the menu). X.PP XAlways setting the attributes is a simplistic method, but Xoften proves most effective. The routines pl_perim() and Xrr_perim() in the download exhibit this approach. Modification Xfor other primitives is straightforward. This style is most Xuseful when drawing operations are scattered throughout the Xprogram, so that keeping track of the current attribute status is Xdifficult. Although inherently inefficient, the difference is not Xvery noticable if the drawing operation requested is itself time Xconsuming. X.PP XIn many applications, such as data graphing programs or X"Draw" packages, the output operations are centralized, forming Xthe primary functionality of the code. In this case, it is both Xeasy and efficient to keep track of attribute status between Xsuccessive drawing operations. X.SH SOLIDS XThere are a wider variety of VDI calls for drawing solid Xfigures. They include rectangle or bar, disk, pie, ellipse, Xelliptical pie, filled rounded rectangle, and filled polygonal Xarea. Of course, filled figure calls also have their own set of Xattributes which you will need to set. X.PP XThe fill color index determines what pen color will be used Xto draw the solid. It is set with: X.FB vsf_color() Xvsf_color(vdi_handle, color); X.FE XColor is just the same as for line drawing. A solid may or Xmay not have a visible border. This is determined with the call: X.FB vsf_perimeter() Xvsf_perimeter(vdi_handle, vis); X.FE XVis is a Boolean. If it is true, the figure will be given a Xsolid one pixel outline in the current fill color index. This is Xoften useful to improve the appearance of solids drawn with a Xdithered fill pattern. If vis is false, then no outline is drawn. X.PP XThere are two parameters which together determine the pattern Xused to fill your figure. They are called interior style and Xinterior index. The style determines the general type of fill, Xand the index is used to select a particular pattern if necessary. XThe style is set with the command: X.FB vsf_interior() Xvsf_interior(vdi_handle, style); X.FE Xwhere style is a value from zero through four. Zero selects a Xhollow style: the fill is performed in color zero, which is Xusually white. Style one selects a solid fill with the current Xfill color. A style of two is called "pattern" and a three is Xcalled "hatch", which are terms somewhat suggestive of the options Xwhich can then be selected using the interior index. Style four Xselects the user defined pattern, which is described below. X.PP XThe interior index is only significant for styles two and Xthree. To set it, use: X.FB vsf_style() Xvsf_style(vdi_handle, index); X.FE X(Be careful here: it is very easy to confuse this call with the Xone above due to the unfortunate choice of name.) The index Xselects the actual drawing pattern. The GEM VDI manual shows fill Xpatterns corresponding to index values from 1 to 24 under style 2, Xand from 1 to 12 under style 3. However, some of these are Ximplemented differently on the ST. Rather than try to describe Xthem all here, I would suggest that you experiment. You can do so Xeasily in ST Logo by opening the Graphics Settings dialog and Xplaying with the style and index values there. X.PP XThe user defined style gives you some interesting options for Xmulti-color fills. It is set with: X.FB vsf_udpat() Xvsf_udpat(vdi_handle, pattern, planes); X.FE XPlanes determines the number of color planes in the pattern Xwhich you supply. It is set to one if you are setting a Xmonochrome pattern. (Remember, monochrome is not necessarily Xblack). It may be set to higher values on color systems: two for XST medium-res mode, or four for low-res mode. If you use a number Xlower than four under low-res, the other planes are zero filled. X.PP XThe pattern parameter is an array of words which is a Xmultiple of 16 words long. The pattern determined is 16 by 16 Xpixels, with each word forming one row of the pattern. The rows Xare arranged top to bottom, with the most significant bit to the Xleft. If you have selected a multi-plane pattern, the entire Xfirst plane is stored, then the second, and so on. X.PP XNote that to use a multi-plane pattern, you set the writing Xmode to replace using vswr_mode(). Since the each plane can be Xdifferent, you can produce multi-colored patterns. If you use a Xwriting color other than black, some of the planes may X"disappear". X.PP XMost of the solids Output Functions have analogous line Xdrawing commands. The polyline command corresponds to the filled Xarea primitive. The filled area routine is: X.FB v_fillarea() Xv_fillarea(vdi_handle, count, pxy); X.FE XCount and pxy are just the same as for v_pline(). If the Xpolygon defined by pxy is not closed, then the VDI will force Xclosure with a straight line from the last to the first point. XThe polygon may be concave or self-intersecting. If perimeter Xshow is on, the area will be outlined. X.PP XOne note of caution is necessary for both v_fillarea() and Xv_pline(). There is a limit on the number of points which may be Xstored in pxy[]. This limit occurs because the contents of pxy[] Xare copied to the intin[] binding array before the VDI is called. XYou can determine the maximum number of vertices by checking Xintout[14] after using the extended inquire function vq_extnd(). X.PP XFor reasons unknown to this writer, there are TWO different Xfilled rectangle commands in the VDI. The first is X.FB vr_recfl() Xvr_recfl(vdi_handle, pxy); X.FE XPxy is a four word array defining two opposite corners of the Xrectangle, just as in vs_clip(). Vr_recfl() uses the fill Xattribute settings, except that it NEVER draws a perimeter. X.PP XThe other rectangle routine is v_bar(), with exactly the same Xarguments as vr_recfl(). The only difference is that the Xperimeter setting IS respected. These two routines are the Xfastest way to produce a solid rectangle using the VDI. They may Xbe used in XOR mode with a BLACK fill color to quickly invert an Xarea of the screen. You can improve the speed even further by Xturning off the clip (if possible), and byte aligning the left and Xright edges of the rectangle. X.PP XSeparate commands are provided for solid circle and ellipse. XThe circle call is: X.FB v_circle() Xv_circle(vdi_handle, x, y, radius); X.FE Xand the ellipse command is: X.FB v_ellipse() Xv_ellipse(vdi_handle, x, y, xrad, yrad); X.FE XAll of the parameters are identical to those given above for Xv_arc() and v_ellarc(). The solid analogue of an arc is a "pie Xslice". The VDI pie commands are: X.FB v_pieslice() Xv_pieslice(vdi_handle, x, y, radius, begin, end); X.FE Xfor a slice from a circular pie, and X.FB v_ellpie() Xv_ellpie(vdi_handle, x, y, xrad, yrad, begin, end); X.FE Xfor a slice from a "squashed" pie. Again, the parameters are Xidentical to those in v_arc() and v_ellarc(). The units and Xdrawing order of angles are also the same. The final solids XOutput Function is: X.FB v_rfbox() Xv_rfbox(vdi_handle, pxy); X.FE Xwhich draws a filled rounded rectangle. The pxy array defines Xtwo two opposite corners of the bounding box, as shown for Xvs_clip(). X.PP XThe issues involved in correctly setting the VDI attributes Xfor a fill operation are identical to those in drawing lines. For Xthose who want to employ the "always set" method, I have again Xincluded two skeleton routines in the download, which can be Xmodified as desired. X.SH TO BE CONTINUED XThis concludes the first part of our expedition through basic XVDI operations. The next issue will tackle the problems of Xdrawing bit mapped text at a reasonable speed. This first pass Xwill not attempt to tackle alternate or proportional fonts, or Xalternate font sizes. Instead, I will concentrate on techniques Xfor squeezing greater performance out of the standard monospaced Xsystem fonts. X.! X.! X.!***************************************************************************** X.!* * X.!* End Part 9 * X.!* * X.!***************************************************************************** SHAR_EOF if test 21188 -ne "`wc -c 'wind9.prf'`" then echo shar: error transmitting "'wind9.prf'" '(should have been 21188 characters)' fi # End of shell archive exit 0 -- Jwahar R. Bammi Usenet: .....!decvax!cwruecmp!bammi CSnet: bammi@case Arpa: bammi%case@csnet-relay CompuServe: 71515,155