akcs.aaron@hpcvbbs.UUCP (Aaron Boonshoft) (04/22/91)
%%HP: T(3)A(R)F(.); DIR @ Hi, I recently graduated from The Ohio State University and moved to @ Corvallis Oregon to pursue a career in handheld computing. As I @ learn more about programming these devices, I have come to realize some @ things about user interfaces. The following summarizes some of what I @ have learned. I hope it is helpful. @********************************************************************* @ +===========================+ @ | HP48 SCIENTIFIC EXPANDABLE| @ A |+-------------------------+| Hi! How are you? @ || <( O )> <( O )> || @ || || / @ FRIENDLY || [ ] [ ] || ______/ @ || [ ][ ] [ ][ ] || @ |+-------------------------+| @ HP 48 |===========================| @ || [A] [B] [C] [D] [E] [F] || @ || MTH PRG CST VAR [^] NXT || @ USER || ['] STO EVL [<] [v] [>] || by @ || SIN COS TAN SQR Y^X 1/X || @ || [ENTER] +/- EEX DEL [<= || @ INTER- || [a] [7] [8] [9] [/] || Aaron Boonshoft @ || [<] [4] [5] [6] [X] || @ || [>] [1] [2] [3] [-] || @ FACE || [ON [0] [.] SPC [+] || @ +===========================+ @ Introduction: @ One of the more challenging aspects of writing professional software @ for the HP 48 is the user interface. Professional software normally @ requires a very clean, friendly, and flexible user interface. @ The software should not generate an error regardless of the keys the @ user presses (including [ATTN]) or of the input data the user enters @ (including total gibberish). The user interface is often time @ consuming to design and debug. It may also account for more @ than half of the code in a project. One way of combating the @ problems of writing user interface code is to write the code in the @ form of subprograms (programs designed to be used by other @ programs). In this form, the code may be used for many different @ projects. This may greatly reduce their size and development time. @ Below are five sets of programs and subprograms. The first set @ just contains examples of how the other four are used. Each of the @ other four contain one major subprogram which, in some cases, uses @ the help of supporting subprograms or other major subprograms. The @ subprograms take care of some general I/O needs and the inputting of @ real numbers. They are not designed to handle all I/O. @ * BOXV is for demonstration only. It directly or indirectly @ makes use of all the other sets. @ * RUN makes interfaces cleaner by taking program objects off the @ stack if the [ATTN] key is pressed. It will also return the @ user to the menu used before the program was run. @ * IPMO adds flexibility by allowing the user to choose a menu option @ or the stack at an INPUT prompt. It makes use of PAUSE. @ * CIA makes interfaces more robust by checking for bad input of real @ numbers and telling the user what's wrong. It will also do @ conversions with unit objects (including ones that have the @ underscore missing.) @ * PAUSE uses an alarm to halt program execution for any number of @ seconds. It can also be used to update the stack display. @ (NOTE: Subprogram EB in the RUN set is also used by IPMO and CIA) @ All of the subprograms have been written as straightforwardly as @ possible to allow for modifications. The only programming trick @ that is used is to store some objects as strings. This technique @ was used four times in IPMO to save about 210 bytes. Note, however, @ that doing this makes the code less obvious and slower to a small @ degree. @********************************************************************* @ BOXV: Box Volume Example @ BV is just an example program for showing how IPMO and CIA can be @ used. BOXV uses RUN to execute BV. BOXV or BV will ask the user @ to input the volume of a box or it will CALC'ulate it from the @ dimensions. A volume of 1.2_ft^3 is used to demonstrate the use of @ default values. To really see why the user interface can be called @ professional, try entering negative numbers or gibberish, entering @ 3ft^3 instead of 3_ft^3 or pressing the ATTN key while running BOXV. @ Executing ERUN demonstrates how RUN deals with an error caused by @ something other than pressing the ATTN key. See the sections below @ this one for more information about RUN, IPMO and CIA. BOXV @ Compute Box Volume ( --> box_volume ) BYTES # 61780d 35.5 \<< 'BV' RUN \>> BV @ Subprogram for BOXV ( --> box_volume ) BYTES # 57289d 419 \<< DO "Box Volume?" ":V:" "1.2_ft^3" 45 {"CALC"} IPMO IF THEN 43 {1_ft 'x > 0'} \-> M C \<< DO M TMENU "Box Width?" ":W:" INPUT C CIA UNTIL END DO M TMENU "Box Depth?" ":D:" INPUT C CIA UNTIL END DO M TMENU "Box Height?" ":H:" INPUT C CIA UNTIL END * * 1 \>> ELSE { 1_ft^3 'x > 0'} CIA END UNTIL END 1_ft^3 * "V" \->TAG \>> ERUN @ Example of RUN catching an error ( --> ) BYTES # 31101d 40 @ Note that a list can be evaluated. \<< { "" 2 * } RUN \>> @********************************************************************* @ RUN: Evaluate Object and Trap Errors @ RUN is designed to evaluate programs and other objects. If the [ATTN] @ key is pressed while using RUN, the stack will be reset to the input @ stack. Unlike the LASTSTACK operation, it does not require the user @ to press any additional keys or have any particular flag setting. @ Using RUN will bring the back the menu and flag settings used before @ the program started. @ Note that there are some cases where pressing the [ATTN] key may not @ be caught by RUN: @ * If [ATTN] is pressed "immediately" after starting RUN @ * If [ATTN] is pressed two are more times "rapidly" @ * If the program being evaluated by RUN contains an IFERR command @ RUN STACK INPUT @ Level 1: Object to be evaluated by RUN @ (other levels may contain input for the object) @ RUN STACK OUTPUT @ If [ATTN] was "not" pressed, the stack will contain the output of @ the object evaluated by RUN. @ If [ATTN] was pressed or the object evaluated with an error, @ the stack will be reset to the input stack minus level 1. RUN @ Evaluate Object BYTES # 57031d 276 \<< DEPTH ROLLD DEPTH 1 - \->LIST RCLMENU RCLF \-> prg stk men flg \<< IFERR stk LIST\-> DROP prg EVAL THEN IF ERRN #0d SAME NOT THEN CLLCD "An error has occurred" 1 DISP "while evaluating..." 2 DISP prg 3 DISP ERRN 5 DISP ERRM 6 DISP EB 3 FREEZE END DEPTH DROPN stk LIST\-> DROP END flg STOF men TMENU \>> \>> EB @ Error Beep ( --> ) BYTES # 32606d 33.5 \<< "1400 .1" STR\-> BEEP \>> @********************************************************************* @ IPMO: INPUT with MENU Options @ IPMO may be used instead of (really in addition to) the built-in @ INPUT command. It allows the user to choose a menu option rather @ than inputting the requested data. It also allows the user to @ access an empty stack to compute the input if necessary. @ IPMO STACK INPUT @ Level 5: INPUT command "stack prompt" (3 lines or less) @ Level 4: INPUT command "command-line prompt" (list not allowed) @ Level 3: Default value, any object, (should be "" if no default) @ Level 2: Menu displayed during stack INPUT (real number or list) @ Level 1: Menu displayed during menu INPUT (must be a list) @ IPMO STACK OUTPUT @ Level 2: INPUT command "result" if 0 in level 1 @ Level 1: Exit Condition, 0 for INPUT, 1 to 6 for menu key @ When the user is asked for input by IPMO, one of five things happens @ depending on which key is pressed first: @ ( 1.) [ENTER] key will cause IPMO to end. The default value and @ a 0 will be the stack output. @ ( 2.) [0],[1],[2],...,[9],[.],backspace or [EXX] keys will cause @ the 2nd level menu to be displayed and the real INPUT command will @ be executed with the appropriate data appended to the command line @ prompt. The default, if any, will vanish from the display. The @ "result" from INPUT and the number 0 will be the stack output. @ ( 3.) Any menu key that is not blank will cause IPMO to end. @ A number from 1 to 6 corresponding to the menu key (going left to @ right) will be the stack output. @ ( 4.) [CONT] will cause the stack to be saved and IPMO to HALT. @ An empty stack is then available for the user to compute the @ required input. When [CONT] is pressed again, IPMO will make @ the object in level 1 a string and leave it and 0 on the stack. @ ( 5.) [ATTN] key will cause an error. An error trap should be @ used outside of IPMO. RUN is recommended. @ Pressing any other key will result in an error tone. The @ only exceptions are shifted versions of most of the keys above. @ Only [CONT] and [ATTN] are shift sensitive. IPMO @ INPUT with MENU Options BYTES # 48856d 669.5 \<< 5 DUPN CLLCD TMENU DROP + 3 \->GROB SWAP 3 DISP "(Press CONT for stack)" 1 DISP LCD\-> "{#0d#46d}" STR\-> ROT REPL \->LCD @sON EN M6 M5 M4 M3 M2 M1 [0][1][2][3][4][5][6][7][8][9][.][<][EXX] @ -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 "{91 51 16 15 14 13 12 11 92 82 83 84 72 73 74 62 63 64 93 55 53}" STR\-> DO DUP -1 WAIT IP POS 8 - CASE DUP 1 \>= THEN C$ 41 {"0""1""2""3""4""5""6""7""8""9"".""""1E"} STR\-> SWAP GET 5 ROLLD DROP2 TMENU DROP + INPUT 0 1 END DUP -5 \>= THEN NEG 1 + 3 PICK C$ 14 {""""""""""""} STR\-> + OVER GET IF "" \=/ THEN 7 ROLLD 6 DROPN 1 ELSE EB NOT END END DUP -6 == THEN 4 DROPN + SWAP DROP 0 1 END -7 == THEN DROP2 TMENU 3 DROPN DEPTH \->LIST \-> \255 \<< 0 PAUSE "Place desired input on stack level 1 and then press CONT to continue running program." 1 DISP 3 FREEZE HALT IF DEPTH THEN \->STR DEPTH ROLLD DEPTH 1 - DROPN ELSE "" END \255 LIST\-> 1 + ROLL \>> 0 1 END EB 0 END UNTIL END \>> @********************************************************************* @ CIA: Check Input Acceptability @ CIA will verify that the user has INPUT a valid real number based on @ a check list. The real number may be tagged or have units but it @ must be contained in a string. CIA will use ERR to display what @ is wrong to the user if the INPUT value is not acceptable. @ CIA STACK INPUT @ Level 2: "result", INPUT value @ Level 1: { unt rng }, check list (see below) @ CIA STACK OUTPUT @ Level 2: new_result, if 1 in Stack level 1 (real number) @ Level 1: OK_flag, 1 if "value" OK, 0 otherwise @ The check list must contain two values: @ unt = the desired input units. unt=1 if units will be ignored. @ If the unt is anything else, the INPUT value will be @ CONVERT'ed to those units and then the units will be removed. @ The new_result will be a real number without tags or units. @ 'rng'= an expression which results in 1 if the INPUT value is @ within range or 0 if not. The expression must refer to the @ INPUT value as 'x' as in 'x\>=0' or '2<ABS(x) AND ABS(x)<3'. @ If rng=1, any INPUT value will be within range. @ Note that you may want to tell the user what units are required (if @ any) and what range of values are allowable. This could be done as @ part of the prompt messages for INPUT or IPMO. @ Also note that during the INPUT command, PRG entry mode is used. @ This will cause 3_ft^3 to be entered as 3ft^3 unless you explicitly @ type in "_" character. CIA is smart enough, with the help of ISU, @ to recognize and compensate for this in virtually every case. In @ other words, 3ft^3 will be treated like 3_ft^3 so the user does not @ have type the "_" character when using units. CIA @ Check Input Acceptability BYTES # 57037d 590.5 \<< DEPTH SWAP LIST\-> DROP \-> dep unt rng \<< CASE IFERR STR\-> THEN ISU IFERR STR\-> THEN 1 ELSE 0 END ELSE 0 END THEN DROP " Invalid Syntax" ERR END DEPTH dep - 1 + IF DUP 1 == THEN ROT DTAG 3 ROLLD IF 3 PICK TYPE 0 == 3 PICK TYPE DUP 6 == SWAP 7 == OR AND THEN DROP _ 0 END END DUP THEN 1 + DROPN "Only One Value Allowed" ERR END DROP DTAG DUP TYPE DUP 13 == XOR THEN DROP "Must be a Real Number" ERR END unt 1 SAME NOT OVER TYPE AND IF THEN IFERR unt CONVERT THEN 1 ELSE UVAL 0 END ELSE UVAL 0 END THEN DROP2 " Inconsistent Units" ERR END rng { x } 3 PICK + \|^MATCH DROP \->NUM NOT THEN DROP " Value Out of Range" ERR END 1 END \>> \>> ISU @ Insert Underscore Character BYTES # 39323d 196.5 @ ( "ValueUnits" --> "Value_Units" ) \<< DUP SIZE 1 IF DUP2 \>= THEN FOR n IF "0123456789" OVER n DUP SUB POS THEN IF "^" OVER n 1 - DUP SUB \=/ THEN DUP 1 n SUB "_" + SWAP n 1 + MAXR \->NUM SUB + 0 'n' STO END END -1 STEP ELSE DROP2 END \>> ERR @ Display Input Error ( "message" --> 0 ) BYTES # 10754d 87 \<< CLLCD "Sorry, not acceptable:" 3 DISP 5 DISP {"OK"} TMENU EB -1 WAIT DROP 0 \>> @********************************************************************* @ PAUSE: Timed Program HALT @ PAUSE will set an alarm and HALT. The alarm will CONT the program @ after a given number of seconds. One reason why this is useful is @ that it allows the calculator time to update the stack display. @ PAUSE uses ATCT and ADDT to do some date and time arithmetic. They @ use HP 48 HMS and Date formats. PAUSE @ Timed Program HALT ( seconds --> ) BYTES # 19068d 88 \<< .2 MAX 3600 / \->HMS MEM DROP ATCT \<< DELALARM CONT \>> + STOALARM DROP HALT \>> ATCT @ Add Time to Current Time BYTES # 30370d 38.5 @ ( Delta_Time --> {Date2 Time2} ) Computes Time2 and Date2 by adding @ Delta_Time to the current Time and Date. \<< DATE TIME 2 \->LIST SWAP ADDT \>> ADDT @ Add Time to a Date and a Time BYTES # 50943d 77 @ ( {Date1 Time1} Delta_Time --> {Date2 Time2} ) @ Computes Time2 and Date2 by adding Delta_Time to Time1 and Date1. \<< SWAP LIST\-> DROP ROT HMS+ DUP 24 / IP ROT SWAP DATE+ SWAP 24 MOD 2 \->LIST \>> @********************************************************************* END