home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Ken Long / Ascii Chart-c / ascii_chart.µ.c < prev    next >
Encoding:
Text File  |  1994-12-04  |  14.3 KB  |  491 lines  |  [TEXT/MMCC]

  1. //• --------------------------------------------------------------------- •//
  2. //• --------------------------------------------------------------------- •//
  3. //• Updated to run in THINK C™ v.5.0.4, changed to an applicationand
  4. //• redistributed as a public domain C source demo, on 16 February 1994,
  5. //• by Kenneth A. Long. 
  6. //• --------------------------------------------------------------------- •//
  7. //• --------------------------------------------------------------------- •//
  8. //• Ascii Chart - a Desk Accessory for the Macintosh written by:.
  9. //• Wade S. Blomgren    (c) 1986            version 1.0.
  10. //• UC San Diego.
  11.  
  12. //• Both source and executable files may be freely distributed for.
  13. //• NON-COMMERCIAL USE ONLY provided this copyright notice is left.
  14. //• intact..
  15.  
  16. //• This program is intended as an example for persons beginning to.
  17. //• learn about programming the Macintosh. It is NOT meant to be an.
  18. //• example of excellent programming or a particularly fabulous.
  19. //• idea for a program.  It IS supposed to be chock full of comments.
  20. //• and to have some examples of common uses for the toolbox..
  21.  
  22. //•    This program was written using LightspeedC (c) from Think.
  23. //•    Technologies, INC. and therefore includes material that is.
  24. //•    copyright Think Technologies INC..
  25.  
  26. //•    Some techniques were gleaned from a PD desk accessory called.
  27. //•    ZoomIdle by Paul DuBois, University of Wisconsin.
  28.  
  29. //•    Wade S. Blomgren  UCSD-ACS   mailcode B-028  La Jolla, CA 92093.
  30. //• --------------------------------------------------------------------- •//
  31.  
  32. //• Since this is a DA and not a standalone application we do not have to
  33. //• initialize the various managers. (Yeah!  Right! (kal) :)
  34.  
  35. //• Global Variables for the DA.    (What DA? (kal) :)
  36.  
  37. //• The chart data is stored in two dimensional arrays so we can use the.
  38. //• drawtext routine (faster than repeated calls to drawchar) (IM I-172).
  39. //• --------------------------------------------------------------------- •//
  40.  
  41. char octdata[23][47] = {
  42.     "000 NUL  026 SYC  054 , 102 B 130 X 156 n ",
  43.     "001 SOH  027 ETB  055 - 103 C 131 Y 157 o ",
  44.     "002 STX  030 CAN  056 . 104 D 132 Z 160 p ",
  45.     "003 ETX  031 EM   057 / 105 E 133 [ 161 q ",
  46.     "004 EOT  032 SUB  060 0 106 F 134 \\ 162 r ", //• escape the \ character.
  47.     "005 ENQ  033 ESC  061 1 107 G 135 ] 163 s ",
  48.     "006 ACK  034 FS   062 2 110 H 136 ^ 164 t ",
  49.     "007 BEL  035 GS   063 3 111 I 137 _ 165 u ",
  50.     "010 BS   036 RS   064 4 112 J 140 ` 166 v ",
  51.     "011 HT   037 US   065 5 113 K 141 a 167 w ",
  52.     "012 LF   040 SPA  066 6 114 L 142 b 170 x ",
  53.     "013 VT   041 !    067 7 115 M 143 c 171 y ",
  54.     "014 FF   042 \"    070 8 116 N 144 d 172 z ", //• escape the " character.
  55.     "015 CR   043 #    071 9 117 O 145 e 173 { ",
  56.     "016 SO   044 $    072 : 120 P 146 f 174 | ",
  57.     "017 SI   045 %    073 ; 121 Q 147 g 175 } ",
  58.     "020 DLE  046 &    074 < 122 R 150 h 176 ~ ",
  59.     "021 DC1  047 '    075 = 123 S 151 i 177 DEL",  
  60.     "022 DC2  050 (    076 > 124 T 152 j ",
  61.     "023 DC3  051 )    077 ? 125 U 153 k ",
  62.     "024 DC4  052 *    100 @ 126 V 154 l ",
  63.     "025 NAK  053 +    101 A 127 W 155 m "
  64. };
  65.      
  66. char decdata[23][47] = {
  67.     "000 NUL 022 SYC 044 , 066 B 088 X 110 n ",
  68.     "001 SOH 023 ETB 045 - 067 C 089 Y 111 o ",
  69.     "002 STX 024 CAN 046 . 068 D 090 Z 112 p ",
  70.     "003 ETX 025 EM  047 / 069 E 091 [ 113 q ",
  71.     "004 EOT 026 SUB 048 0 070 F 092 \\ 114 r ", //• escape the \ character.
  72.     "005 ENQ 027 ESC 049 1 071 G 093 ] 115 s ",
  73.     "006 ACK 028 FS  050 2 072 H 094 ^ 116 t ",
  74.     "007 BEL 029 GS  051 3 073 I 095 _ 117 u ",
  75.     "008 BS  030 RS  052 4 074 J 096 ` 118 v ",
  76.     "009 HT  031 US  053 5 075 K 097 a 119 w ",
  77.     "010 LF  032 SPA 054 6 076 L 098 b 120 x ",
  78.     "011 VT  033 !   055 7 077 M 099 c 121 y ",
  79.     "012 FF  034 \"   056 8 078 N 100 d 122 z ", //• escape the " character.
  80.     "013 CR  035 #   057 9 079 O 101 e 123 { ",
  81.     "014 SO  036 $   058 : 080 P 102 f 124 | ",
  82.     "015 SI  037 %   059 ; 081 Q 103 g 125 } ",
  83.     "016 DLE 038 &   060 < 082 R 104 h 126 ~ ",
  84.     "017 DC1 039 '   061 = 083 S 105 i 127 DEL",  
  85.     "018 DC2 040 (   062 > 084 T 106 j ",
  86.     "019 DC3 041 )   063 ? 085 U 107 k ",
  87.     "020 DC4 042 *   064 @ 086 V 108 l ",
  88.     "021 NAK 043 +   065 A 087 W 109 m " 
  89. };
  90.  
  91. char hexdata[23][47] = {
  92.     "000 NUL 016 SYC 02C , 042 B 058 X 06E n ",
  93.     "001 SOH 017 ETB 02D - 043 C 059 Y 06F o ",
  94.     "002 STX 018 CAN 02E . 044 D 05A Z 070 p ",
  95.     "003 ETX 019 EM  02F / 045 E 05B [ 071 q ",
  96.     "004 EOT 01A SUB 030 0 046 F 05C \\ 072 r ", //• escape the \ character.
  97.     "005 ENQ 01B ESC 031 1 047 G 05D ] 073 s ",
  98.     "006 ACK 01C FS  032 2 048 H 05E ^ 074 t ",
  99.     "007 BEL 01D GS  033 3 049 I 05F _ 075 u ",
  100.     "008 BS  01E RS  034 4 04A J 060 ` 076 v ",
  101.     "009 HT  01F US  035 5 04B K 061 a 077 w ",
  102.     "00A LF  020 SPA 036 6 04C L 062 b 078 x ",
  103.     "00B VT  021 !   037 7 04D M 063 c 079 y ",
  104.     "00C FF  022 \"   038 8 04E N 064 d 07A z ", //• escape the " character.
  105.     "00D CR  023 #   039 9 05F O 065 e 07B { ",
  106.     "00E SO  024 $   03A : 050 P 066 f 07C | ",
  107.     "00F SI  025 %   03B ; 051 Q 067 g 07D } ",
  108.     "010 DLE 026 &   03C < 052 R 068 h 07E ~ ",
  109.     "011 DC1 027 '   03D = 053 S 069 i 07F DEL",  
  110.     "012 DC2 028 (   03E > 054 T 06A j ",
  111.     "013 DC3 029 )   03F ? 055 U 06B k ",
  112.     "014 DC4 02A *   040 @ 056 V 06C l ",
  113.     "015 NAK 02B +   041 A 057 W 06D m " 
  114. };
  115.  
  116. //• allocate control handles to the various control buttons.    
  117. ControlHandle OctPtr, HexPtr, DecPtr, BinPtr, AbPtr,
  118.               the_control, whichControl;
  119.  
  120. int line;    //• counter for the text drawing loop.
  121. int y;        //• coordinate variable for positioning the text.
  122. int DAisOpen = 0;    //• flag so we know if the DA is already open.
  123.  
  124. MenuHandle    appleMenu, fileMenu, editMenu, wasteMenu;
  125.  
  126. //• Define rectangles for the DA's window and the control buttons.
  127. //• blanket_rect is the entire data area & is used to erase the data.
  128.  
  129. //•                     Top. Lef. Bot. Rig.
  130. Rect blanket_rect     = {   3,  12, 220, 280 };
  131. Rect bounds         = {  60,  60, 335, 350 };
  132.  
  133. Rect OctRect         = { 225,  15, 242,  65 };
  134. Rect HexRect         = { 225,  85, 242, 135 };
  135. Rect DecRect         = { 225, 155, 242, 205 };
  136. Rect BinRect         = { 225, 225, 242, 275 };  //• Not used, yet.
  137.  
  138. Rect AbRect          = { 250,  85, 270, 205 };
  139. Rect windowBounds     = {  40,  40, 150, 150 };
  140. Rect circleStart     = {  10,  10, 100, 100 };
  141. Rect dragRect;
  142.  
  143. WindowPtr    ascii_window;
  144.  
  145. enum    {
  146.     appleID = 1,
  147.     fileID,
  148.     editID,
  149.     wasteID
  150.     };
  151.  
  152. enum    {
  153.     openItem = 1,
  154.     closeItem,
  155.     quitItem = 4
  156.     };
  157.     
  158. //• various functions begin here - see 'main' for calling sequence.
  159.  
  160. //• Window update routine.
  161. //• If it's a result of a radix change, scope is 0 (update everything).
  162. //• If it is a system update event, update only the area that needs it, 
  163. //• by using BeginUpdate & EndUpdate.
  164. //• (see calls to 'Update_The_Display()' in 'main' and 'DAEvent'.
  165.  
  166. Update_The_Display(int scope)
  167. {
  168.     GrafPtr currentPort;
  169.     Ptr dataAddr;                //• a generic 'pointer' data type.
  170.  
  171.     GetPort(¤tPort);        //• save the current grafport  (IM I-447).
  172.     SetPort(ascii_window);    //• set the grafport to our window.
  173.  
  174.     if (scope)
  175.         BeginUpdate(ascii_window);   //• set the visRgn to only the part.
  176.                                         //• that needs updating (IM I-292).
  177.                                         //• otherwise, redraw the whole window.
  178.                     
  179.     DrawControls(ascii_window);      //• draw the controls in our window.
  180.     EraseRect(&blanket_rect);        //• blank out the old data (IM I-177).
  181.     y = 10;
  182.     
  183.     if (the_control == OctPtr)    //• determine which control was pressed.
  184.         dataAddr = (Ptr) octdata;   //• & cast the address of the 2D array.
  185.     else
  186.         if (the_control == DecPtr) //• into our generic data pointer.
  187.             dataAddr = (Ptr) decdata;
  188.     else
  189.         if (the_control == HexPtr)
  190.             dataAddr = (Ptr) hexdata;
  191.         
  192.     TextFont(4);   //• Monaco font for evenly spaced columns (IM I-219).
  193.     TextSize(9);   //• these are quickdraw functions.
  194.  
  195.     for (line  = 0; line  < 22; line++)
  196.     {
  197.     
  198.     //• we have 23 lines per 'page' - use quickdraw to output the data.
  199.     //• the starting address for DrawText is (line# * 47) to get to the.
  200.     //• proper position in the 2D array.
  201.         
  202.         MoveTo(12, y);        
  203.         DrawText(dataAddr + (line * 47), 0, 46);    //• (IM I-172).
  204.         y = y + 10;
  205.     }
  206.  
  207.     if (scope)
  208.         EndUpdate(ascii_window);        
  209.                                 
  210.     SetPort(currentPort);        //• restore the current grafport (IM I-447).
  211.  
  212. }    //• end of Update_The_Display.
  213.  
  214.  
  215. Add_Some_Controls()            //• open the desk accessory.
  216. {
  217.     GrafPtr currentPort;
  218.     
  219.     GetPort(¤tPort);    //• save the current grafport.
  220.     
  221.     ascii_window = NewWindow(0, &bounds, "\pAscii Chart", 0, 16, (WindowPtr)-1L, 1, 0);
  222. //    ((WindowPeek) (ascii_window))->windowKind = dce->dCtlRefNum;
  223.     
  224. //     SetPort(ascii_window);    //• set the grafport to our window.
  225.      ShowWindow(ascii_window); //• display the window.
  226.      
  227.      
  228.     //• Create new controls for the various radixes and the about box.
  229.     //• Set the octal radix control to be 'on'... (IM I-319).
  230.     OctPtr = NewControl(ascii_window, &OctRect, "\pOct.", 1, 1, 0, 1, 2, 0);
  231.      HexPtr = NewControl(ascii_window, &HexRect, "\pHex", 1, 0, 0, 1, 2, 0);
  232.      DecPtr = NewControl(ascii_window, &DecRect, "\pDec.", 1, 0, 0, 1, 2, 0);
  233. //• BinPtr = NewControl(ascii_window, &BinRect, "\pBin.", 1, 0, 0, 1, 2, 0);
  234.      AbPtr  = NewControl(ascii_window, &AbRect, "\pFast Quit", 1, 1, 0, 0, 0, 0);
  235.  
  236.      the_control = OctPtr;    //• set default for current control button.
  237.      
  238.     //• We do not need to explicitly call "Update_The_Display" because 
  239.     //• the open routine will cause an update event to be sent to the 
  240.     //• Desk Manager.
  241.         
  242.     SetPort(currentPort);        //• restore original grafport.
  243.         
  244.     return(0);
  245.  
  246. }
  247.  
  248. Do_Content_Click (EventRecord *theEvent)
  249. {
  250.     //• convert the location to local coordinates  (IM I-193, 323).
  251.     GlobalToLocal(&(theEvent->where));
  252.     
  253.     //• find where mouse was pressed - (the part code) (IM I-334).
  254.     
  255.     switch (FindControl(theEvent->where, ascii_window, &whichControl)) 
  256.     {
  257.         case (11):        //• a RADIO button has been hit - track it.
  258.             
  259.             //• track control routine makes sure mouse is released in button.
  260.             if (TrackControl(whichControl, theEvent->where, 0))
  261.             {    
  262.                 if (whichControl != the_control)
  263.                 {    //• a new radix.
  264.                     SetCtlValue(the_control, 0);
  265.                     the_control = whichControl; //• set new 'current' ctl.
  266.                     SetCtlValue(the_control, 1);
  267.                     Update_The_Display(0);            //• update whole window.
  268.                 }                //• end new radix.
  269.             }                //• end if track control.
  270.         break;
  271.             
  272.         case (10):    //• SIMPLE button (must be the about box).
  273.             Clean_Up_Things();
  274.         break;
  275.                     
  276.     } //• end possible control mousedown.
  277.     LocalToGlobal(&theEvent->where); //• put the coordinates back to global.
  278. }
  279.  
  280. //• close DA function. (What DA?)
  281.  
  282. Clean_Up_Things()
  283. {
  284.    GrafPtr currentPort;
  285.  
  286.    GetPort(¤tPort);        //• save the system's grafport.
  287.    DisposeWindow(ascii_window);    //• dispose our window.
  288.    ascii_window = 0L;            //• set the driver's window ptr to null.
  289.                                     //• (IM I-446).
  290.    SetPort(currentPort);        //• restore the system's grafport.
  291.    ExitToShell();
  292.  
  293. }
  294.  
  295. void Set_Up_The_Window(void)
  296. {
  297.     dragRect = qd.screenBits.bounds;
  298.     
  299.     ascii_window = NewWindow(0, &bounds, "\pAscii Chart", 0, 16, (WindowPtr)-1L, 1, 0);
  300.     SetPort(ascii_window);
  301. }
  302.  
  303. void Set_Up_The_Menus(void)
  304. {
  305.     InsertMenu(appleMenu = NewMenu(appleID, "\p\024"), 0);
  306.     InsertMenu(fileMenu = NewMenu(fileID, "\pFile"), 0);
  307.     InsertMenu(editMenu = NewMenu(editID, "\pEdit"), 0);
  308.     InsertMenu(wasteMenu = NewMenu(wasteID, "\pUseless Menu"), 0);
  309.     DrawMenuBar();
  310.     AddResMenu(appleMenu, 'DRVR');
  311.     AppendMenu(fileMenu, "\pOpen/O;Close/W;(-;Quit/Q");
  312.     AppendMenu(editMenu, "\pUndo/Z;(-;Cut/X;Copy/C;Paste/V;Clear");
  313.     AppendMenu(wasteMenu, "\p(-;(-;(-;(-;(-;(-;(-;(-;(-;(-;(-;(-;(-;(-;Told Ya");
  314. }
  315.  
  316. static void enable(MenuHandle menu, short item, short ok)
  317. {
  318.     if (ok)
  319.         EnableItem(menu, item);
  320.     else
  321.         DisableItem(menu, item);
  322. }
  323.  
  324. void Make_Menu_Adjustments(void)
  325. {
  326.     register WindowPeek wp = (WindowPeek) FrontWindow();
  327.     short kind = wp ? wp->windowKind : 0;
  328.     Boolean DA = kind < 0;
  329.     
  330.     enable(editMenu, 1, DA);
  331.     enable(editMenu, 3, DA);
  332.     enable(editMenu, 4, DA);
  333.     enable(editMenu, 5, DA);
  334.     enable(editMenu, 6, DA);
  335.     
  336.     enable(fileMenu, openItem, !((WindowPeek) ascii_window)->visible);
  337.     enable(fileMenu, closeItem, DA || ((WindowPeek) ascii_window)->visible);
  338. }
  339.  
  340. void Handle_The_Menus (long mSelect)
  341. {
  342.     int            menuID = HiWord(mSelect);
  343.     int            menuItem = LoWord(mSelect);
  344.     Str255        name;
  345.     GrafPtr        savePort;
  346.     WindowPeek    frontWindow;
  347.     
  348.     switch (menuID)
  349.       {
  350.       case    appleID:
  351.         GetPort(&savePort);
  352.         GetItem(appleMenu, menuItem, name);
  353.         OpenDeskAcc(name);
  354.         SetPort(savePort);
  355.         break;
  356.     
  357.       case    fileID:
  358.         switch (menuItem)
  359.           {
  360.           case    openItem:
  361.             ShowWindow(ascii_window);
  362.             SelectWindow(ascii_window);
  363.             break;
  364.                                 
  365.           case    closeItem:
  366.             if ((frontWindow = (WindowPeek) FrontWindow()) == 0L)
  367.               break;
  368.               
  369.             if (frontWindow->windowKind < 0)
  370.               CloseDeskAcc(frontWindow->windowKind);
  371.             else if ((frontWindow = (WindowPeek) ascii_window) != NULL)
  372.               HideWindow(ascii_window);
  373.                         break;
  374.                         
  375.           case    quitItem:
  376.             ExitToShell();
  377.             break;
  378.           }
  379.         break;
  380.                   
  381.       case    editID:
  382.         if (!SystemEdit(menuItem-1))
  383.           SysBeep(5);
  384.         break;
  385.         
  386.       case    wasteID:
  387.         break;
  388.       }
  389. }
  390.  
  391. void Initialize_The_Managers(void)
  392. {
  393.     MaxApplZone();
  394.     
  395.     InitGraf(&qd.thePort);
  396.     InitFonts();
  397.     FlushEvents(everyEvent, 0);
  398.     InitWindows();
  399.     InitMenus();
  400.     TEInit();
  401.     InitDialogs(0L);
  402.     InitCursor();
  403.  
  404. }
  405.  
  406. void Handle_Mouse_Clicks (EventRecord    *theEvent)
  407. {
  408.     WindowPtr    theWindow;
  409.     int            windowCode = FindWindow (theEvent->where, &theWindow);
  410.     
  411.     switch (windowCode)
  412.       {
  413.       case inSysWindow: 
  414.         SystemClick (theEvent, theWindow);
  415.         break;
  416.         
  417.       case inMenuBar:
  418.           Make_Menu_Adjustments();
  419.         Handle_The_Menus(MenuSelect(theEvent->where));
  420.         break;
  421.         
  422.       case inDrag:
  423.           if (theWindow == ascii_window)
  424.             DragWindow(ascii_window, theEvent->where, &dragRect);
  425.             break;
  426.             
  427.       case inContent:
  428.             Do_Content_Click (theEvent);
  429. //          if (theWindow == ascii_window)
  430. //            {
  431. //            if (theWindow != FrontWindow())
  432. //              SelectWindow(ascii_window);
  433. //            else
  434. //              InvalRect(&ascii_window->portRect);
  435. //            }
  436.           break;
  437.           
  438.       case inGoAway:
  439.           if (theWindow == ascii_window && 
  440.               TrackGoAway(ascii_window, theEvent->where))
  441.               ExitToShell ();
  442.             break;
  443.       }
  444. }
  445.  
  446. void Handle_The_Events(void)
  447. {
  448.     int            ok;
  449.     EventRecord    theEvent;
  450.  
  451.     HiliteMenu(0);
  452.     SystemTask ();        //• Handle desk accessories.
  453.     
  454.     ok = GetNextEvent (everyEvent, &theEvent);
  455.     if (ok)
  456.       switch (theEvent.what)
  457.         {
  458.         case mouseDown:
  459.             Handle_Mouse_Clicks(&theEvent);
  460.         break;
  461.             
  462.         case keyDown: 
  463.         case autoKey:
  464.             if ((theEvent.modifiers & cmdKey) != 0)
  465.             {
  466.                 Make_Menu_Adjustments();
  467.                 Handle_The_Menus(MenuKey((char) (theEvent.message & charCodeMask)));
  468.             }
  469.         break;
  470.             
  471.         case updateEvt:
  472.             Update_The_Display(1);
  473.             break;
  474.             
  475.         case activateEvt:
  476.             Update_The_Display(1);
  477.         break;
  478.         }
  479. }
  480.  
  481. void main( void)
  482. {
  483.     Initialize_The_Managers();
  484.     Set_Up_The_Menus();
  485.     Set_Up_The_Window();
  486.     Add_Some_Controls();
  487.         
  488.     for (;;)
  489.         Handle_The_Events();
  490. }
  491.