home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / Help / Help.c next >
Encoding:
Text File  |  1993-12-04  |  10.8 KB  |  496 lines  |  [TEXT/KAHL]

  1. typedef struct
  2. {
  3.     ResType    hlpType;
  4.     short    hlpID;
  5. }    SHelpInfo, *SHelpInfoPtr, **SHelpInfoHandle;
  6.  
  7.  
  8.  
  9. typedef struct
  10. {
  11.     ListHandle    myList;
  12.     TEHandle    myTEh;
  13.     PicHandle    myPic;
  14.     Rect        myPicRect;
  15.     SHelpInfo    mSHelpInfo[1];
  16. }    HelpInfo, *HelpInfoPtr, **HelpInfoHandle;
  17.  
  18.  
  19.  
  20.  
  21. // constants
  22.  
  23. #define    kInFront        (WindowPtr)-1L
  24. #define    kListItem        2
  25. #define    kTextItem        3
  26. #define    kMargin            2
  27.  
  28. #define    kCR                0x0d
  29. #define    kEnter            0x03
  30. #define    kDelete            0x08
  31. #define    kEscape            0x1B
  32. #define    kDownArrow        0x1F
  33. #define    kUpArrow        0x1E
  34.  
  35. #define    SysEnvironsTrap    0xA090
  36. #define    UnknownTrap        0xA89F
  37.  
  38.  
  39. // prototypes
  40.  
  41. void SetupDialog(DialogPtr theDialog);
  42. void PrepareFreeDialog(DialogPtr theDialog);
  43.  
  44. Boolean InMyList(DialogPtr theDialog, Point p, short modifiers);
  45. pascal void ListDrawProc(DialogPtr theDialog,short theItem);
  46. pascal void TextDrawProc(DialogPtr theDialog,short theItem);
  47. pascal Boolean MyDialogFilter(DialogPtr theDialog,EventRecord *ev,short *itemHit);
  48. void HandleKeyPress(DialogPtr theDialog,char theChar);
  49. void HandleActivate(DialogPtr theDialog);
  50.  
  51. void DrawHelpText(short TextIndex, HelpInfoHandle myHelpInfoHandle);
  52.  
  53.  
  54. void DrawAHelpPICT(TEHandle theTE, SHelpInfoPtr mySHelpInfoPtr, short TextIndex, HelpInfoHandle myHelpInfoHandle);
  55. void DrawAHelpTEXT(TEHandle theTE, SHelpInfoPtr mySHelpInfoPtr, short TextIndex);
  56.  
  57. void SetSelection(DialogPtr theDialog, short Offset);
  58.  
  59. ControlHandle GetScrollBar(DialogPtr theDialog);
  60. TEHandle GetListInfoHandle(DialogPtr theDialog);
  61.  
  62.  
  63.  
  64.  
  65. short TestForColor()
  66. {
  67.   short        hasColor;                            /* Color Flag            */
  68.   GrafPtr    aPort;                                /* Quickdraw port        */
  69.   SysEnvRec    sysEnv;
  70.   hasColor = false;                                /* Test for color        */
  71.   if ((long)NGetTrapAddress(SysEnvironsTrap, OSTrap) !=
  72.   (long)NGetTrapAddress(UnknownTrap, ToolTrap))
  73.   {
  74.      SysEnvirons(1, &sysEnv);
  75.      GetPort(&aPort);
  76.      if (sysEnv.hasColorQD)
  77.      {
  78.        if ((*((*((GDHandle)GetGDevice()))->gdPMap))->pixelSize > 1)        /* Check graphic's device depth    */
  79.        {
  80.          hasColor = BitTst(&aPort->portBits.rowBytes, 0L);            /* Set color            */
  81.        }
  82.      }
  83.    }
  84.    return(hasColor);
  85. }
  86.  
  87.  
  88.  
  89. void DoHelp(void)
  90. {
  91.     DialogPtr    theDialog;
  92.     short        item;
  93.     
  94.     theDialog = GetNewDialog(128, 0L, kInFront);
  95.     SetupDialog(theDialog);
  96.         
  97.     do
  98.     {
  99.         ModalDialog(MyDialogFilter, &item);
  100.     }while(item != ok);
  101.     
  102.     PrepareFreeDialog(theDialog);
  103.     DisposeDialog(theDialog);
  104. }
  105.  
  106.  
  107. void SetupDialog(DialogPtr theDialog)
  108. {
  109.     short            iType, iCnt, i;
  110.     Handle            iHndl;
  111.     Rect            iRect, rView, rBounds;
  112.     Point            pCellSz;
  113.     TEHandle        theTE;
  114.     ListHandle        theList;
  115.     HelpInfoHandle    myHelpInfoHandle;
  116.     SHelpInfoHandle    hRsrc;
  117.     FontInfo        fInfo;
  118.     
  119.     SetPort(theDialog);
  120.     GetDItem(theDialog,kListItem,&iType,&iHndl,&iRect);
  121.     
  122.     TextFont(geneva);
  123.     TextSize(9);
  124.     TextFace(bold);
  125.     
  126.     GetFontInfo(&fInfo);
  127.     pCellSz.h = 0;
  128.     pCellSz.v = fInfo.ascent + fInfo.descent + fInfo.leading;
  129.     iRect.bottom = iRect.top + ((iRect.bottom - iRect.top) / pCellSz.v) * pCellSz.v;
  130.     InsetRect(&iRect, -1, -1);
  131.     SetDItem(theDialog,kListItem,iType,ListDrawProc,&iRect);
  132.     
  133.     rView = iRect;
  134.     rView.right -= 14;
  135.     InsetRect(&rView, 1, 1);
  136.  
  137.     SetRect(&rBounds,0,0,1,0);
  138.      
  139.     
  140.     
  141.     theList = LNew(&rView,&rBounds,pCellSz,0,theDialog,TRUE,TRUE,FALSE,TRUE);
  142.     LDoDraw(FALSE, theList);
  143.     iCnt = Count1Resources('MHLP');
  144.     myHelpInfoHandle = NewHandle(sizeof(HelpInfo) + sizeof(SHelpInfo) * (iCnt - 1));
  145.     pCellSz.h = 0;
  146.     for(i = 1; i <= iCnt; i++)
  147.     {
  148.         short    rID;
  149.         ResType    rType;
  150.         Str255    rName;
  151.         
  152.         pCellSz.v = LAddRow(1, 999, theList);
  153.         hRsrc = Get1IndResource('MHLP', i);
  154.         GetResInfo(hRsrc, &rID, &rType, rName);
  155.         LSetCell(rName + 1, *rName, pCellSz, theList);
  156.         
  157.         (*myHelpInfoHandle)->mSHelpInfo[i - 1].hlpID = (*hRsrc)->hlpID;
  158.         (*myHelpInfoHandle)->mSHelpInfo[i - 1].hlpType = (*hRsrc)->hlpType;
  159.         ReleaseResource(hRsrc);
  160.     }
  161.     (*myHelpInfoHandle)->myList = theList;
  162.     pCellSz.h = 0; pCellSz.v = 0;
  163.     LSetSelect(TRUE, pCellSz, theList);
  164.  
  165.     
  166.  
  167.     GetDItem(theDialog,kTextItem,&iType,&iHndl,&iRect);
  168.     SetDItem(theDialog,kTextItem,iType,TextDrawProc,&iRect);
  169.     InsetRect(&iRect, kMargin, kMargin);
  170.     (*myHelpInfoHandle)->myTEh = TEStylNew(&iRect, &iRect);
  171.     (*myHelpInfoHandle)->myPic = 0L;
  172.     
  173.     TextFont(0);
  174.     TextSize(0);
  175.     TextFace(0);
  176.     
  177.     DrawHelpText(0, myHelpInfoHandle);
  178.     SetWRefCon(theDialog,(long)myHelpInfoHandle);
  179.     LDoDraw(TRUE, theList);
  180. }
  181.  
  182.  
  183.  
  184.  
  185. void PrepareFreeDialog(DialogPtr theDialog)
  186. {
  187.     HelpInfoHandle    myHelpInfoHandle;
  188.     
  189.     myHelpInfoHandle = GetListInfoHandle(theDialog);
  190.     if((*myHelpInfoHandle)->myPic)
  191.         ReleaseResource((*myHelpInfoHandle)->myPic);
  192.     LDispose((*myHelpInfoHandle)->myList);
  193.     TEDispose((*myHelpInfoHandle)->myTEh);
  194.     DisposHandle(myHelpInfoHandle);
  195. }
  196.  
  197.  
  198.  
  199. pascal void ListDrawProc(DialogPtr theDialog,short theItem)
  200. {
  201.     short        iType, hasColor;
  202.     Handle        iHndl;
  203.     Rect        iRect;
  204.     GrafPtr        savePort;
  205.     RGBColor    SaveColor;
  206.     HelpInfoHandle    myHelpInfoHandle;
  207.     
  208.     GetPort(&savePort);
  209.     SetPort(theDialog);
  210.     TextFont(geneva);
  211.     TextSize(9);
  212.     TextFace(bold);
  213.     myHelpInfoHandle = GetListInfoHandle(theDialog);
  214.     hasColor = TestForColor();
  215.     if(hasColor)
  216.         GetBackColor(&SaveColor);
  217.     BackColor(whiteColor);
  218.     GetDItem(theDialog,theItem,&iType,&iHndl,&iRect);
  219.     EraseRect(&iRect);
  220.     FrameRect(&iRect);
  221.     LUpdate(theDialog->visRgn, (*myHelpInfoHandle)->myList);
  222.     if(hasColor)
  223.         RGBBackColor(&SaveColor);
  224.     TextFont(0);
  225.     TextSize(0);
  226.     TextFace(0);
  227.     SetPort(savePort);
  228. }
  229.  
  230.  
  231.  
  232. pascal void TextDrawProc(DialogPtr theDialog,short theItem)
  233. {
  234.     short        iType, hasColor;
  235.     Handle        iHndl;
  236.     Rect        iRect;
  237.     GrafPtr        savePort;
  238.     RGBColor    SaveColor;
  239.     HelpInfoHandle    myHelpInfoHandle;
  240.     
  241.     GetPort(&savePort);
  242.     SetPort(theDialog);
  243.     myHelpInfoHandle = GetListInfoHandle(theDialog);
  244.     hasColor = TestForColor();
  245.     if(hasColor)
  246.         GetBackColor(&SaveColor);
  247.     GetDItem(theDialog,theItem,&iType,&iHndl,&iRect);
  248.     EraseRect(&iRect);
  249.     if((*myHelpInfoHandle)->myPic)
  250.         DrawPicture((*myHelpInfoHandle)->myPic, &(*myHelpInfoHandle)->myPicRect);
  251.     else
  252.         TEUpdate(&iRect, (*myHelpInfoHandle)->myTEh);
  253.     if(hasColor)
  254.         RGBBackColor(&SaveColor);
  255.     SetPort(savePort);
  256. }
  257.  
  258.  
  259.  
  260.  
  261. pascal Boolean MyDialogFilter(DialogPtr theDialog, EventRecord *ev, short *itemHit)
  262. {
  263.     char theChar;
  264.     
  265.     switch (ev->what)
  266.     {
  267.         case keyDown:
  268.         case autoKey:
  269.             theChar = (ev->message & charCodeMask);
  270.             switch(theChar)
  271.             {
  272.                 case kCR:
  273.                 case kEnter:
  274.                 case kEscape:
  275.                     *itemHit = ok;
  276.                     return TRUE;
  277.                 case kDownArrow:
  278.                     SetSelection(theDialog, +1);
  279.                     break;
  280.                 case kUpArrow:
  281.                     SetSelection(theDialog, -1);
  282.                     break;
  283.                 default:
  284.                     return FALSE;
  285.             }
  286.         case activateEvt:
  287.             HandleActivate(theDialog);
  288.             return false;
  289.         case mouseDown:
  290.         {
  291.             if(InMyList(theDialog, ev->where, ev->modifiers))
  292.                 return(TRUE);
  293.             else
  294.                 return(FALSE);
  295.                 
  296.         }
  297.         default:
  298.             return false;
  299.     }
  300. }
  301.  
  302.  
  303. void SetSelection(DialogPtr theDialog, short Offset)
  304. {
  305.     HelpInfoHandle    myHelpInfoHandle;
  306.     ListHandle        theList;
  307.     GrafPtr            savePort;
  308.     Cell            theCell;
  309.     short            hasColor, NewSel;
  310.     RGBColor        SaveColor;
  311.     
  312.     GetPort(&savePort);
  313.     SetPort(theDialog);
  314.     TextFont(geneva);
  315.     TextSize(9);
  316.     TextFace(bold);
  317.     hasColor = TestForColor();
  318.     if(hasColor)
  319.         GetBackColor(&SaveColor);
  320.     BackColor(whiteColor);
  321.     myHelpInfoHandle = GetListInfoHandle(theDialog);
  322.     theList = (*myHelpInfoHandle)->myList;
  323.     
  324.     theCell.h = theCell.v = 0;
  325.     LGetSelect(TRUE, &theCell, theList);
  326.     NewSel = theCell.v + Offset;
  327.     if((NewSel >= (*theList)->dataBounds.top) && (NewSel < (*theList)->dataBounds.bottom))
  328.     {
  329.         LSetSelect(FALSE, theCell, theList);
  330.         theCell.v = NewSel;
  331.     
  332.         LSetSelect(TRUE, theCell, theList);
  333.         LAutoScroll(theList);
  334.     }
  335.     if(hasColor)
  336.         RGBBackColor(&SaveColor);
  337.     DrawHelpText(theCell.v, myHelpInfoHandle);
  338.     TextFont(0);
  339.     TextSize(0);
  340.     TextFace(0);
  341.     SetPort(savePort);
  342. }
  343.  
  344.  
  345. Boolean InMyList(DialogPtr theDialog, Point p, short modifiers)
  346. {
  347.     Rect            iRect;
  348.     short            type, hasColor;
  349.     Handle            iHndle;
  350.     GrafPtr            savePort;
  351.     HelpInfoHandle    myHelpInfoHandle;
  352.     RGBColor        SaveColor;
  353.     Cell            theOriginalCell, theCell;
  354.     ListHandle        theList;
  355.     
  356.     GetPort(&savePort);
  357.     SetPort(theDialog);
  358.     myHelpInfoHandle = GetListInfoHandle(theDialog);
  359.     theList = (*myHelpInfoHandle)->myList;
  360.     HLock(theList);
  361.     GlobalToLocal(&p);
  362.     GetDItem(theDialog, kListItem, &type, &iHndle, &iRect);
  363.     if(PtInRect(p, &iRect))
  364.     {
  365.         theOriginalCell.h = theOriginalCell.v = 0;
  366.         LGetSelect(TRUE, &theOriginalCell, theList);
  367.         
  368.         TextFont(geneva);
  369.         TextSize(9);
  370.         TextFace(bold);
  371.         hasColor = TestForColor();
  372.         if(hasColor)
  373.             GetBackColor(&SaveColor);
  374.         BackColor(whiteColor);
  375.         LClick(p, modifiers, theList);
  376.         if(hasColor)
  377.             RGBBackColor(&SaveColor);
  378.         TextFont(0);
  379.         TextSize(0);
  380.         TextFace(0);
  381.         
  382.         theCell.h = theCell.v = 0;
  383.         LGetSelect(TRUE, &theCell, theList);
  384.         if(theCell.v != theOriginalCell.v)
  385.             DrawHelpText(theCell.v, myHelpInfoHandle);
  386.         HUnlock(theList);
  387.         SetPort(savePort);
  388.         return(TRUE);
  389.     }
  390.     SetPort(savePort);
  391.     return(FALSE);
  392. }
  393.  
  394.  
  395. void DrawHelpText(short TextIndex, HelpInfoHandle myHelpInfoHandle)
  396. {
  397.     TEHandle        theTE;
  398.     SHelpInfoPtr    mySHelpInfoPtr;
  399.     
  400.     theTE = (*myHelpInfoHandle)->myTEh;
  401.     HLock(myHelpInfoHandle);
  402.     mySHelpInfoPtr = (*myHelpInfoHandle)->mSHelpInfo;
  403.     
  404.     if((*myHelpInfoHandle)->myPic)
  405.     {
  406.         EraseRect(&(*myHelpInfoHandle)->myPicRect);
  407.         ReleaseResource((*myHelpInfoHandle)->myPic);
  408.     }
  409.     switch(mySHelpInfoPtr[TextIndex].hlpType)
  410.     {
  411.         case 'TEXT':
  412.             DrawAHelpTEXT(theTE, mySHelpInfoPtr, TextIndex);
  413.             (*myHelpInfoHandle)->myPic = 0L;
  414.             break;
  415.         case 'PICT':
  416.             DrawAHelpPICT(theTE, mySHelpInfoPtr, TextIndex, myHelpInfoHandle);
  417.             break;
  418.         default:
  419.             SysBeep(1);
  420.     }
  421.     HUnlock(myHelpInfoHandle);
  422. }
  423.  
  424.  
  425. void DrawAHelpPICT(TEHandle theTE, SHelpInfoPtr mySHelpInfoPtr, short TextIndex, HelpInfoHandle myHelpInfoHandle)
  426. {
  427.     PicHandle    thePic;
  428.     Rect        r;
  429.     long        wide, high;
  430.     
  431.     (*theTE)->selStart = 0;
  432.     (*theTE)->selEnd = 32000;
  433.     TEDelete(theTE);
  434.     thePic = Get1Resource('PICT', mySHelpInfoPtr[TextIndex].hlpID);
  435.     HLock(thePic);
  436.     r = (*thePic)->picFrame;
  437.     wide = r.right - r.left;
  438.     high = r.bottom - r.top;
  439.     SetRect(&r, (*theTE)->destRect.left, (*theTE)->destRect.top, (*theTE)->destRect.left + wide, (*theTE)->destRect.top + high);
  440.     DrawPicture(thePic, &r);
  441.     (*myHelpInfoHandle)->myPicRect = r;
  442.     (*myHelpInfoHandle)->myPic = thePic;
  443.     HUnlock(thePic);
  444.     
  445. }
  446.  
  447.  
  448.  
  449. void DrawAHelpTEXT(TEHandle theTE, SHelpInfoPtr mySHelpInfoPtr, short TextIndex)
  450. {
  451.     Handle            myText;
  452.     StScrpHandle    SavedStyle;
  453.     
  454.     myText = Get1Resource('TEXT', mySHelpInfoPtr[TextIndex].hlpID);
  455.     HLock(myText);
  456.     SavedStyle = Get1Resource('styl', mySHelpInfoPtr[TextIndex].hlpID);
  457.     HLock(SavedStyle);
  458.     
  459.     (*theTE)->selStart = 0;
  460.     (*theTE)->selEnd = 32000;
  461.     TEDelete(theTE);
  462.     TEActivate(theTE);
  463.     if((*SavedStyle)->scrpNStyles > 0)
  464.         TEStylInsert(*myText, GetHandleSize(myText), SavedStyle, theTE);
  465.     else
  466.         TEInsert(*myText, GetHandleSize(myText), theTE);
  467.     TEDeactivate(theTE);
  468.     HUnlock(SavedStyle);
  469.     HUnlock(myText);
  470.     ReleaseResource(myText);
  471.     ReleaseResource(SavedStyle);
  472. }
  473.  
  474.  
  475.  
  476.  
  477. void HandleActivate(DialogPtr theDialog)
  478. {
  479.     HelpInfoHandle    myHelpInfoHandle;
  480.  
  481.     myHelpInfoHandle = GetListInfoHandle(theDialog);
  482.     TextFont(geneva);
  483.     TextSize(9);
  484.     TextFace(bold);
  485.     LActivate(TRUE, (*myHelpInfoHandle)->myList);
  486.     TextFont(0);
  487.     TextSize(0);
  488.     TextFace(0);
  489. }
  490.  
  491.  
  492.  
  493. TEHandle GetListInfoHandle(DialogPtr theDialog)
  494. {
  495.     return( (HelpInfoHandle)GetWRefCon((WindowPtr)theDialog) );
  496. }