home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Frameworks / TransSkel 3.18 / Demos / C Demos / MultiSkel / MSkelHelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-18  |  7.8 KB  |  306 lines  |  [TEXT/KAHL]

  1. /*
  2.  * TransSkel multiple-window demonstration: Help module
  3.  * 
  4.  * This module handles a help window, in which text may be scrolled but
  5.  * not edited.  A TextEdit record is used to hold the text, though.
  6.  * 
  7.  * 21 Apr 88 Paul DuBois
  8.  * 29 Jan 89
  9.  * - Conversion for TransSkel 2.0.
  10.  * 12 Jan 91
  11.  * - Conversion for TransSkel 3.0.
  12.  */
  13.  
  14. # include    "TransSkel.h"
  15.  
  16. # include    "MultiSkel.h"
  17.  
  18.  
  19. static TEHandle            teHelp;        /* handle to help window TextEdit record */
  20. static ControlHandle    helpScroll;    /* help window scroll bar */
  21. static short            helpLine;    /* line currently at top of window */
  22. static short            halfPage;    /* number of lines in half a window */
  23.  
  24.  
  25. /*
  26.  * Scroll to the correct position.  lDelta is the
  27.  * amount to CHANGE the current scroll setting by.
  28.  */
  29.  
  30. static void
  31. DoScroll (short lDelta)
  32. {
  33. short    newLine;
  34.  
  35.     newLine = helpLine + lDelta;
  36.     if (newLine < 0)
  37.         newLine = 0;
  38.     if (newLine > GetCtlMax (helpScroll))
  39.         newLine = GetCtlMax (helpScroll);
  40.     SetCtlValue (helpScroll, newLine);
  41.     lDelta = (helpLine - newLine ) * (**teHelp).lineHeight;
  42.     TEScroll (0, lDelta, teHelp);
  43.     helpLine = newLine;
  44. }
  45.  
  46.  
  47. /*
  48.  * Filter proc for tracking mousedown in scroll bar.  The part code
  49.  * of the part originally hit is stored as the control's reference
  50.  * value.
  51.  *
  52.  * The "void" had better be there!  Otherwise the compiler will treat
  53.  * it as an integer function, not a procedure.
  54.  */
  55.  
  56. static pascal void
  57. TrackScroll (ControlHandle theScroll, short partCode)
  58. {
  59. short            lDelta;
  60.  
  61.     if (partCode == GetCRefCon (theScroll))    /* still in same part? */
  62.     {
  63.         switch (partCode)
  64.         {
  65.             case inUpButton: lDelta = -1; break;
  66.             case inDownButton: lDelta = 1; break;
  67.             case inPageUp: lDelta = -halfPage; break;
  68.             case inPageDown: lDelta = halfPage; break;
  69.         }
  70.         DoScroll (lDelta);
  71.     }
  72. }
  73.  
  74.  
  75. /* Compatibility machinery for non-universal header compilation */
  76.  
  77. # if !skelUnivHeaders
  78.  
  79. typedef pascal void (*ControlActionProcPtr)(ControlHandle theControl, short partCode);
  80. typedef ControlActionProcPtr ControlActionUPP;
  81.  
  82. # endif
  83.  
  84. /*
  85.  * Set up a variable to point to the scroll tracking procedure.  For 68K code this
  86.  * is just a direct pointer to TrackScroll().  For PowerPC code it is a
  87.  * routine descriptor into which the address of TrackScroll() is stuffed.
  88.  */
  89.  
  90. # if skelPPC        /* PowerPC code */
  91.  
  92. static RoutineDescriptor    trackDesc =
  93.         BUILD_ROUTINE_DESCRIPTOR(uppControlActionProcInfo, TrackScroll);
  94. static ControlActionUPP    trackProc = (ControlActionUPP) &trackDesc;
  95.  
  96. # else                /* 68K code */
  97.  
  98. static ControlActionUPP    trackProc = TrackScroll;
  99.  
  100. # endif
  101.  
  102.  
  103. /*
  104.  * Handle hits in scroll bar
  105.  */
  106.  
  107. static pascal void
  108. Mouse (Point pt, long t, short mods)
  109. {
  110. short    thePart;
  111.  
  112.         if ((thePart = TestControl (helpScroll, pt)) == inThumb)
  113.         {
  114.             (void) TrackControl (helpScroll, pt, nil);
  115.             DoScroll (GetCtlValue (helpScroll) - helpLine);
  116.         }
  117.         else if (thePart != 0)
  118.         {
  119.             SetCRefCon (helpScroll, (long) thePart);
  120.             (void) TrackControl (helpScroll, pt, trackProc);
  121.         }
  122. }
  123.  
  124.  
  125. /*
  126.  * Update help window.  The update event might be in response to a
  127.  * window resizing.  If so, resize the rects and recalc the linestarts
  128.  * of the text.  To resize the rects, only the right edge of the
  129.  * destRect need be changed (the bottom is not used, and the left and
  130.  * top should not be changed). The viewRect should be sized to the
  131.  * screen.  Pull text down if necessary to fill window.
  132.  */
  133.  
  134. static pascal void
  135. Update (Boolean resized)
  136. {
  137. Rect    r;
  138. short    visLines;
  139. short    lHeight;
  140. short    topLines;
  141. short    nLines;
  142. short    scrollLines;
  143.  
  144.     r = helpWind->portRect;
  145.     EraseRect (&r);
  146.     if (resized)
  147.     {
  148.         r.left += 4;
  149.         r.bottom -= 2;
  150.         r.top += 2;
  151.         r.right -= 19;
  152.         (**teHelp).destRect.right = r.right;
  153.         (**teHelp).viewRect = r;
  154.         TECalText (teHelp);
  155.         lHeight = (**teHelp).lineHeight;
  156.         nLines = (**teHelp).nLines;
  157.         visLines = (r.bottom - r.top) / lHeight;
  158.         halfPage = visLines / 2;
  159.         topLines = (r.top - (**teHelp).destRect.top) / lHeight;
  160.         scrollLines = visLines - (nLines - topLines);
  161.         if (scrollLines > 0 && topLines > 0)
  162.         {
  163.             if (scrollLines > topLines)
  164.                 scrollLines = topLines;
  165.             TEScroll (0, scrollLines * lHeight, teHelp);
  166.         }
  167.         scrollLines = nLines - visLines;
  168.         helpLine = (r.top - (**teHelp).destRect.top) / lHeight;
  169.  
  170.         /*
  171.          * Move and resize the scroll bar as well.  The ValidRect call is done
  172.          * because the HideControl adds the control bounds box to the update
  173.          * region - which would generate another update event!  Since everything
  174.          * gets redrawn below, the ValidRect is used to cancel the update.
  175.          */
  176.  
  177.         HideControl (helpScroll);
  178.         r = helpWind->portRect;
  179.         r.left = r.right - 15;
  180.         r.bottom -= 14;
  181.         --r.top;
  182.         ++r.right;
  183.         SizeControl (helpScroll, r.right - r.left, r.bottom - r.top);
  184.         MoveControl (helpScroll, r.left, r.top);
  185.         SetCtlMax (helpScroll, nLines - visLines < 0 ? 0 : nLines - visLines);
  186.         SetCtlValue (helpScroll, helpLine);
  187.         /*if (scrollLines <= 0)
  188.             HiliteControl (helpScroll, (scrollLines > 0 ? 0 : 255));*/
  189.         ShowControl (helpScroll);
  190.         /*if (GetCtlValue (helpScroll) > scrollLines)
  191.             DoScroll (GetCtlValue (helpScroll) - scrollLines);*/
  192.     }
  193.     DrawGrowBox (helpWind);
  194.     DrawControls (helpWind);    /* redraw scroll bar */
  195.     r = (**teHelp).viewRect;
  196.     TEUpdate (&r, teHelp);        /* redraw text display */
  197.     ValidRect (&helpWind->portRect);
  198. }
  199.  
  200.  
  201. /*
  202.  * When the window comes active, disable the Edit menu and highlight
  203.  * the scroll bar if there are any lines not visible in the content
  204.  * region.  When the window is deactivated, enable the Edit menu and
  205.  * un-highlight the scroll bar.
  206.  */
  207.  
  208. static pascal void
  209. Activate (Boolean active)
  210. {
  211.     DrawGrowBox (helpWind);
  212.     if (active)
  213.     {
  214.         DisableItem (editMenu, 0);
  215.         HiliteControl (helpScroll,
  216.                     (GetCtlMax (helpScroll) > 0 ? normalHilite : dimHilite));
  217.     }
  218.     else
  219.     {
  220.         EnableItem (editMenu, 0);
  221.         HiliteControl (helpScroll, dimHilite);
  222.     }
  223.     DrawMenuBar ();
  224. }
  225.  
  226.  
  227. static pascal void
  228. Clobber (void)
  229. {
  230.     TEDispose (teHelp);
  231.     DisposeControl (helpScroll);
  232.     DisposeWindow (helpWind);
  233. }
  234.  
  235.  
  236. void
  237. HelpWindInit (void)
  238. {
  239. Rect    r;
  240. Handle    textHandle;
  241. short    visLines;
  242. short    scrollLines;
  243.  
  244.     if (SkelQuery (skelQHasColorQD))
  245.         helpWind = GetNewCWindow (helpWindRes, nil, (WindowPtr) -1L);
  246.     else
  247.         helpWind = GetNewWindow (helpWindRes, nil, (WindowPtr) -1L);
  248.     if (helpWind == (WindowPtr) nil)
  249.         return;
  250.     (void) SkelWindow (helpWind,
  251.                 Mouse,        /* handle clicks in scrollbar */
  252.                 nil,        /* ignore keyclicks */
  253.                 Update,
  254.                 Activate,
  255.                 nil,        /* no close proc */
  256.                 Clobber,    /* disposal proc */
  257.                 nil,        /* no idle proc */
  258.                 false);
  259.  
  260.     TextFont (0);
  261.     TextSize (0);
  262.  
  263.     r = helpWind->portRect;
  264.     r.left += 4;
  265.     r.bottom -= 2;
  266.     r.top += 2;
  267.     r.right -= 19;
  268.     teHelp = TENew (&r, &r);
  269.     textHandle = GetResource ('TEXT', helpTextRes);    /* read help text */
  270.     HLock (textHandle);        /* lock it and insert into TERec */
  271.     TEInsert (*textHandle, GetHandleSize (textHandle), teHelp);
  272.     HUnlock (textHandle);
  273.     ReleaseResource (textHandle);    /* done with it, so goodbye */
  274.     /*
  275.      * Now figure out how many lines will fit in the window and how many
  276.      * will not.  Determine the number of lines in half a window for use
  277.      * in tracking clicks in the page up and page down regions of the
  278.      * scroll bar.  Then create the scroll bar .  Make sure the borders
  279.      * overlap the window frame and the frame of the grow box.
  280.      */
  281.     visLines = (r.bottom - r.top) / (**teHelp).lineHeight;
  282.     scrollLines = (**teHelp).nLines - visLines;
  283.     halfPage = visLines / 2;
  284.     helpLine = 0;
  285.     r = helpWind->portRect;
  286.     r.left = r.right - 15;
  287.     r.bottom -= 14;
  288.     --r.top;
  289.     ++r.right;
  290.     /*
  291.      * Build the scroll bar.  Don't need to bother testing whether to
  292.      * highlight it or not, since that will be done in response to the
  293.      * activate event.
  294.      */
  295.     helpScroll = NewControl (helpWind, &r, "\p", true,
  296.                     helpLine, 0, scrollLines, scrollBarProc, 0L);
  297.  
  298.     /*
  299.      * GetNewWindow generates an update event for entire portRect.
  300.      * Cancel it, since the everything has been drawn already,
  301.      * except for the grow box (which will be drawn in response
  302.      * to the activate event).
  303.      */
  304.     ValidRect (&helpWind->portRect);
  305. }
  306.