home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a067 / 1.img / GRUMP501.EXE / GRUMP.CH < prev    next >
Encoding:
Text File  |  1991-08-24  |  14.8 KB  |  368 lines

  1. /*
  2.    File: GRUMP.CH
  3.    System: GRUMPFISH LIBRARY
  4.    Author: Greg Lief
  5.    Copyright (c) 1988-90, Greg Lief
  6.    Standard header file for Grumpfish Library Version 3.0
  7.    WARNING: You must #include this file if you want to use any of the
  8.             following functions:  LoadArray(), Center(), PopBox(),
  9.             DropBox(), WaitOff(), StrPad(), TIMEWORD(), Datest(), ByeByeBox()
  10. */
  11.  
  12. //───── constants for HELPDEV() automatically pulled in from GRUMPH.CH
  13. #ifndef _HELP_DEFINED
  14.    #include "Grumph.ch"
  15. #endif
  16.  
  17. //───── simple defines for a simple man (me, not you)
  18. #define YES           .T.
  19. #define NO            .F.
  20. #define SPACEBAR      32
  21. #define CRLF          CHR(13)+CHR(10)
  22. #define NETERR_MSG    "Network error, could not add/edit at this time"
  23.  
  24. //───── sneaky way to return an array and a logical value from the
  25. //───── same function
  26. #xtranslate loadarray(<array>, <file>) => ;
  27.            (len(<array> := gloadarray(<file>)) > 0)
  28.  
  29. /* Nantucket's boxes don't clear the area, so I wrote my own */
  30. #xtranslate SINGLEBOX(<top>, <left>, <bottom>, <right> [,<color>] ) => ;
  31.            DispBox(<top>, <left>, <bottom>, <right>, "┌─┐│┘─└│ " [, <color>] )
  32. #xtranslate DOUBLEBOX(<top>, <left>, <bottom>, <right> [,<color>] ) => ;
  33.            DispBox(<top>, <left>, <bottom>, <right>, '╔═╗║╝═╚║ ' [, <color>] )
  34.  
  35. /* ¡the ubiquitous Center() function! */
  36. #xtranslate CENTER(<row>, <msg>, <width> [, <color>] ) => ;
  37.             DevPos( <row>, int(( <width> - len( <msg> )) / 2)) ; ;
  38.             DevOut( <msg> [,<color>] )
  39.  
  40. #xtranslate CENTER(<row>, <msg> [, , <color> ] ) => ;
  41.             DevPos( <row>, int((maxcol() + 1 - len( <msg> )) / 2)) ; ;
  42.             DevOut( <msg> [, <color>] )
  43.  
  44. /*
  45.    a modified CENTER(), which uses setpos() and dispout() to ensure
  46.    that output always goes to the screen and never the printer
  47. */
  48. #xtranslate SCRNCENTER(<row>, <msg> [, <color> ] ) => ;
  49.             SetPos( <row>, int(( maxcol()+1 - len(<msg>)) / 2)) ; ;
  50.             DispOut( <msg> [, <color>] )
  51.  
  52. /*
  53.    a modified @..SAY which uses setpos() and dispout() to ensure
  54.    that output always goes to the screen and never the printer
  55. */
  56. #xcommand @ <row>, <col> SSAY <xpr> [COLOR <color>] => ;
  57.          SetPos( <row>, <col> ) ; DispOut( <xpr> [, <color>] )
  58.  
  59. /* shorthand to lop off the rightmost element of an array */
  60. #xtranslate Truncate( <a> ) => asize( <a>, len(<a>) - 1)
  61.  
  62. /*
  63.    Function to delete an array element and resize the array in one fell swoop
  64.    Made possible because ADEL() returns a reference to the array in question
  65. */
  66. #xtranslate AKill( <a>, <e> ) => asize( adel( <a>, <e> ), len( <a> ) - 1 )
  67.  
  68. /* constants for CLRSCR() -- fancy screen clearing function */
  69. #define WINDOWDOWN  1
  70. #define WINDOWUP    2
  71. #define DOORRIGHT   3
  72. #define DOORLEFT    4
  73. #define CURTAINOPEN 5
  74. #define CURTAINSHUT 6
  75. #define CAMERALENS  7
  76. #define DIAGONAL    8
  77. #define HALVES      9
  78.  
  79.  
  80. /* constants for COLORSET() (Grumpfish color management - see $COLSET.PRG) */
  81. #define C_GETS                       1
  82. #define C_MESSAGE                    2
  83. #define C_MESSAGEBLINK               3
  84. #define C_WAITMESSAGE                4
  85. #define C_WAITMESSAGEBLINK           5
  86. #define C_YESNO                      6
  87. #define C_ERRORBOX                   7
  88. #define C_ERRORMESSAGE               8
  89. #define C_MEMEDIT_BOX                9
  90. #define C_MEMEDIT_WINDOW            10
  91. #define C_STOPWATCH_BOX             11
  92. #define C_STOPWATCH_WINDOW          12
  93. #define C_CALCULATOR_BOX            13
  94. #define C_CALCULATOR_WINDOW         14
  95. #define C_NOTEPAD_BOX               15
  96. #define C_NOTEPAD_WINDOW            16
  97. #define C_PHONEBOOK_WINDOW1         17
  98. #define C_PHONEBOOK_WINDOW2         18
  99. #define C_CALENDAR                  19
  100. #define C_APPOINTMENT               20
  101. #define C_APICK_BOXOUTLINE          21
  102. #define C_APICK_STATUSBAR           22
  103. #define C_APICK_INDICATOR           23
  104. #define C_APICK_UNSELECTED          24
  105. #define C_APICK_CURRENT             25
  106. #define C_APICK_TAGGED              26
  107. #define C_APICK_TAGGEDCURRENT       27
  108. #define C_APICK_UNAVAILABLE         28
  109. #define C_APICK_UNAVAILABLECURRENT  29
  110. #define C_MENU_UNSELECTED           30
  111. #define C_MENU_SELECTED             31
  112. #define C_GRUMPBROW_BOX             32
  113. #define C_GRUMPBROW_SAY             33
  114. #define C_GRUMPBROW_GET             34
  115.  
  116.  
  117. /* no more BoxType() function with this handy array of box outlines */
  118. #define BOXFRAMES {'╔═╗║╝═╚║ ╣╠╠╣', '┌─┐│┘─└│ ┤├├┤', '╒═╕│╛═╘│ ╣╠╞╡', ;
  119.                    '╓─╖║╜─╙║ ┤├╟╢', '█▀███▄██ ████', SPACE(12) }
  120.  
  121.  
  122. /* simplification of APICK() -- no need to remember order of parameters */
  123. #xcommand APICK <var>                ;
  124.          ARRAY <array>               ;
  125.          [ TOP <top> ]               ;
  126.          [ LEFT <left> ]             ;
  127.          [ BOTTOM <bottom> ]         ;
  128.          [ RIGHT <right> ]           ;
  129.          [ BOXCOLOR <boxcolor> ]     ;
  130.          [ BARCOLOR <barcolor> ]     ;
  131.          [ STATCOLOR <statcolor> ]   ;
  132.          [ LENGTH <length> ]         ;
  133.          [ <tagging:TAGGING> ]       ;
  134.          [ UNSELECTED <unsel>]       ;
  135.          [ HIGHLIGHT <highlight>]    ;
  136.          [ INITIAL <initial>]        ;
  137.          [ SELECTED <selected>]      ;
  138.          [ UNAVAILABLE <unava>]      ;
  139.          [ TITLE <title>]            ;
  140.          [ <nowrap:NOWRAP> ]         ;
  141.                               =>     ;
  142.          <var> := APick( <top>, <left>, <bottom>, <right>, <array>, ;
  143.                   <boxcolor>, <barcolor>, <statcolor>, <length>,    ;
  144.                   <.tagging.>, <unsel>, <highlight>, <initial>,     ;
  145.                   <selected>, <unava>, <title>, ! <.nowrap.> )
  146.  
  147. /* simplification of BOXGET() -- no need to remember order of parameters */
  148. #xcommand BOXGET <var>            ;
  149.          PROMPT <prom>            ;
  150.          [ PICTURE <pict>  ]      ;
  151.          [ VALID <valid>   ]      ;
  152.          [ BOXCOLOR <boxcolor> ]  ;
  153.          [ COLOR <color>   ]      ;
  154.          [ ROW <row>       ]      ;
  155.          [ COLUMN <column> ]      ;
  156.          [ TITLE <title> ]        ;
  157.          [ <norest:NORESTORE> ]   ;
  158.          [ <restall:RESTOREALL> ] ;
  159.          [ <double:DOUBLE> ]      ;
  160.                               =>  ;
  161.          BoxGet(<prom>, <row>, <column>,                                   ;
  162.             getnew( maxrow() + 1, maxcol() + 1,                            ;
  163.             { | _grumpy | if(pcount() = 0, <var>, <var> := _grumpy ) },    ;
  164.             <(var)>, <pict>, <color> ), <{valid}>, <boxcolor>, <.norest.>, ;
  165.             <.restall.>, <.double.>, <title> )
  166.  
  167. /* simplification of GRUMPBROW() -- no need to remember order of parameters */
  168. #xcommand GRUMPBROW               ;
  169.          [ SECURITY <sec> ]       ;
  170.          [ TOP <top> ]            ;
  171.          [ LEFT <left> ]          ;
  172.          [ BOTTOM <bottom> ]      ;
  173.          [ RIGHT <right> ]        ;
  174.          [ <nobox:NOBOX> ]        ;
  175.          [ FIELDS <fields> ]      ;
  176.          [ HEADINGS <headings> ]  ;
  177.          [ PICTURES <pictures> ]  ;
  178.          [ ALTERNATES <alts> ]    ;
  179.          [ LOW <low> ]            ;
  180.          [ HIGH <high> ]          ;
  181.                               =>  ;
  182.          GrumpBrow(<sec>, <top>, <left>, <bottom>, <right>, ! <.nobox.>,   ;
  183.                    <fields>, <headings>, <pictures>, <alts>, <low>, <high>)
  184.  
  185. /* simplification of SHADOWBOX() -- no need to remember order of parameters */
  186. #xcommand SHADOWBOX               ;
  187.          [ BUFFER <buffer> ]      ;
  188.          [ TOP <top> ]            ;
  189.          [ LEFT <left> ]          ;
  190.          [ BOTTOM <bottom> ]      ;
  191.          [ RIGHT <right> ]        ;
  192.          [ TYPE <type> ]          ;
  193.          [ TITLE <title> ]        ;
  194.          [ CROSSBAR <crossbar> ]  ;
  195.          [ COLOR <color> ]        ;
  196.                               =>  ;
  197.          [<buffer> := ] ShadowBox(<top>, <left>, <bottom>, <right>, ;
  198.                                <type>, <title>, <crossbar>, <color>)
  199.  
  200. /* PopBox() & DropBox() have been consolidated into one function: PopNDrop() */
  201. #xtranslate popbox( <parms,...> )  => PopNDrop(1, <parms>)
  202. #xtranslate dropbox( <parms,...> ) => PopNDrop(2, <parms>)
  203.  
  204. /* Music Maestro Please!! -- even if you scoff at the prospect of using
  205.    audio feedback in your programs, it still behooves you to look at the
  206.    coding techniques presented here.  The first call to one of the musical
  207.    themes (e.g., Charge) is preprocessed into a multi-dimensional array
  208.    (contained note frequency and duration) which is passed to the function
  209.    Tunes().  Tunes() is then translated again by the preprocessor into an
  210.    AEVAL() statement which invokes the TONE() function to play one note for
  211.    each element in the array.  This principle is quite enlightening...
  212.    (NOTE: public domain themes only due to the great GrumpFun snafu)  */
  213.  
  214. #xcommand Charge => tunes({ {523,2}, {698,2}, {880,2}, {1046,4}, ;
  215.                             {880,2}, {1046,8} } )
  216. #xcommand NannyBoo => tunes( { {196,4}, {196,4}, {164,4}, {220,4}, ;
  217.                                {196,8}, {164,8} } )
  218. #xcommand TheFifth => tunes( { {392,2}, {392,2}, {392,2}, {311,8} } )
  219. #xcommand tunes(<a>) => aeval(<a>, { | a | tone(a\[1], a\[2]) } )
  220.  
  221. /* while we're on the subject of music, here are some manifest constants */
  222. #define MUSIC_ERROR           440
  223. #define MUSIC_WAITON          {800, 1600}
  224. #define MUSIC_ALERT           880
  225. #define MUSIC_RASPBERRY       50      // insulting but necessary
  226. #define MUSIC_TTY             25      // use in TTY() and TTY2()
  227.  
  228. /* and here are frequency equivalents for six octaves - write your own tunes */
  229. #define T_C1                  130.8
  230. #define T_CSHARP1             138.6
  231. #define T_D1                  146.8
  232. #define T_DSHARP1             155.6
  233. #define T_E1                  164.8
  234. #define T_F1                  174.6
  235. #define T_FSHARP1             185.0
  236. #define T_G1                  196.0
  237. #define T_GSHARP1             207.7
  238. #define T_A1                  220.0
  239. #define T_ASHARP1             233.1
  240. #define T_B1                  246.9
  241. #define T_C2                  261.7
  242. #define T_CSHARP2             277.2
  243. #define T_D2                  293.7
  244. #define T_DSHARP2             311.1
  245. #define T_E2                  329.6
  246. #define T_F2                  349.2
  247. #define T_FSHARP2             370.0
  248. #define T_G2                  392.0
  249. #define T_GSHARP2             415.3
  250. #define T_A2                  440.0
  251. #define T_ASHARP2             466.2
  252. #define T_B2                  493.9
  253. #define T_C3                  523.4
  254. #define T_CSHARP3             554.4
  255. #define T_D3                  587.4
  256. #define T_DSHARP3             622.2
  257. #define T_E3                  659.2
  258. #define T_F3                  698.4
  259. #define T_FSHARP3             740.0
  260. #define T_G3                  784.0
  261. #define T_GSHARP3             830.6
  262. #define T_A3                  880.0
  263. #define T_ASHARP3             932.4
  264. #define T_B3                  987.8
  265. #define T_C4                 1046.8
  266. #define T_CSHARP4            1108.8
  267. #define T_D4                 1174.8
  268. #define T_DSHARP4            1244.4
  269. #define T_E4                 1318.4
  270. #define T_F4                 1396.8
  271. #define T_FSHARP4            1480.0
  272. #define T_G4                 1568.0
  273. #define T_GSHARP4            1660.6
  274. #define T_A4                 1760.0
  275. #define T_ASHARP4            1864.8
  276. #define T_B4                 1975.6
  277. #define T_C5                 2093.6
  278. #define T_CSHARP5            2217.6
  279. #define T_D5                 2349.6
  280. #define T_DSHARP5            2488.8
  281. #define T_E5                 2636.8
  282. #define T_F5                 2793.6
  283. #define T_FSHARP5            2960.0
  284. #define T_G5                 3136.0
  285. #define T_GSHARP5            3321.2
  286. #define T_A5                 3520.0
  287. #define T_ASHARP5            3729.6
  288. #define T_B5                 3951.2
  289. #define T_C6                 4187.2
  290. #define T_CSHARP6            4435.2
  291. #define T_D6                 4699.2
  292. #define T_DSHARP6            4977.6
  293. #define T_E6                 5273.6
  294. #define T_F6                 5587.2
  295. #define T_FSHARP6            5920.0
  296. #define T_G6                 6272.0
  297. #define T_GSHARP6            6642.4
  298. #define T_A6                 7040.0
  299. #define T_ASHARP6            7459.2
  300. #define T_B6                 7902.4
  301.  
  302.  
  303. /* WAITOFF() is now a preprocessor function that calls WAITON() with
  304.    a logical as the first parameter, which indicates to WAITON() that
  305.    it must restore the affected portion of the screen...              */
  306. #xcommand waitoff( [<sound:ON,NOISE,SOUND>] ) => WaitOn(.F., <.sound.>)
  307.  
  308.  
  309. /* my STRPAD() function is no longer necessary in light of Clipper's PADR() */
  310. #xtranslate strpad(<msg>, <length>) => PADR(<msg>, <length>)
  311.  
  312.  
  313. /* add or remove file extensions */
  314. #xtranslate AddExtension(<file>, <ext>) => ;
  315.        <file> := upper(<file>) + ;
  316.        if(! "." + upper(<ext>) $ upper(<file>), "." + upper(<ext>), '')
  317. #xtranslate StripExt( <fname> ) => ;
  318.       if('.' $ <fname>, substr( <fname>, 1, at('.', <fname>) - 1), <fname> )
  319.  
  320.  
  321. //───── default all parameters to a specific value if not passed to function
  322. #xcommand DEFAULT <param> TO <value> => ;
  323.          <param> := IF(<param> == NIL, <value>, <param>)
  324.  
  325. //───── several small functions that are better suited for this treatment
  326. #xtranslate timeword() => if(seconds() \< 43200, 'morning', ;
  327.                           if(seconds() \< 64800, 'afternoon', 'evening'))
  328. #xtranslate Datest(<date>) => if(empty(<date>), space(8), dtoc(<date>))
  329. #xtranslate ByeByeBox(<buff>) => ;
  330.             restscreen(<buff>\[1], <buff>\[2], <buff>\[3], <buff>\[4], ;
  331.                        <buff>\[5])
  332.  
  333. /* manifest constants for calendaring concerns (POPDATE, CALENDAR, GETDATE) */
  334. #define FIRSTDAY_ROW      datecoords[1]
  335. #define FIRSTDAY_COL      datecoords[2]
  336. #define LASTDAY_ROW       datecoords[3]
  337. #define LASTDAY_COL       datecoords[4]
  338. #define LASTDAY_NUMBER    datecoords[5]
  339. #define CURRENTDAY_ROW    datecoords[6]
  340. #define CURRENTDAY_COL    datecoords[7]
  341. #define SYSTEMDATE_ROW    datecoords[8]
  342. #define SYSTEMDATE_COL    datecoords[9]
  343. #define CURRENTAPPTS      datecoords[10]
  344.  
  345. /* compile a character string to a code block -- often preferable to do
  346.    this instead of macro expansion for LOCATE conditions et cetera     */
  347. #xtranslate MakeBlock(<string>) =>  &("{ | | " + <string> + "}")
  348.  
  349. /* handy functions to parse a screen variable for text/color attributes */
  350. #xtranslate TextAt(<row>, <col>)  => ;
  351.                   left(savescreen( <row>, <col>, <row>, <col> ), 1)
  352. #xtranslate ColorAt(<row>, <col>) => ;
  353.                   Color_N2S(right(savescreen( <row>, <col>, <row>, <col> ), 1))
  354.  
  355.  
  356. //───── manifest constants for GInkeyTime() function
  357. #define GINKEYTIME    1
  358. #define GINKEYEVENT   2
  359. #define GINKEYEXIT    3
  360.  
  361. //───── directive to make GInkeyTime() function call simpler
  362. #xcommand INKEY [TIMEOUT <timeout>] [EVENT <event>] [EXIT <exit>] => ;
  363.           [GInkeyTime(GINKEYTIME,  <timeout>) ;]          ;
  364.           [GInkeyTime(GINKEYEVENT, <{event}>) ;]           ;
  365.           [GInkeyTime(GINKEYEXIT,  <{exit}>) ]
  366.  
  367. * eof: GRUMP.CH
  368.