home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / luschsrc.sit / text.c < prev    next >
Text File  |  1990-05-23  |  12KB  |  507 lines

  1. /********************************************************************************
  2.  *    text.c
  3.  *
  4.  *    Text Window Management Package
  5.  *
  6.  *    ⌐1989, Motorola Inc.  All rights reserved.
  7.  ********************************************************************************/
  8.  
  9.  
  10. #include "applic.h"
  11. #include "window.h"
  12. #include "text.h"
  13.  
  14.  
  15. /* Create a window info handle with a text item
  16.  */
  17. WindowPtr
  18. TextWindow (windID, top, left, isActive)
  19.     register WORD windID;
  20.     register WORD top, left;
  21.     register Boolean isActive;
  22. {
  23.     register WindowPtr theWindow;
  24.     register InfoPtr infoPtr;
  25.     Rect destRect, viewRect;
  26.     GrafPtr savePort;
  27.  
  28.     if (theWindow = WindAllocate(windID, isActive)) {
  29.         GetPort(&savePort);
  30.         SetPort(theWindow);
  31.     
  32.         /* Setup the window graf port
  33.          */
  34.         infoPtr = (InfoPtr) GetWRefCon(theWindow);
  35.         SetRect(&(infoPtr->offset), top, left, 100, 100);
  36.         infoPtr->kind = wkText;
  37.             
  38.         TextFont(FONTNUM);
  39.         TextSize(FONTSIZE);
  40.             
  41.         /* Create the TE and the scrollbar
  42.          */
  43.         viewRect = destRect = theWindow->portRect;
  44.         infoPtr->item.text.teHdl = TENew(&destRect, &viewRect);
  45.          infoPtr->item.text.scroll =    NewControl(theWindow, &viewRect, "\pV", FALSE, 0, 0, 0, scrollBarProc, NULL);
  46.  
  47.         /* Fit into the window
  48.          */
  49.         TextAdjust(theWindow);
  50.         TextWindReset(theWindow);
  51.         TextActivate(isActive, theWindow);
  52.  
  53.         SetPort(savePort);
  54.     }
  55.  
  56.     return theWindow;
  57. }
  58.  
  59.  
  60. /* Resize the text edit view rect and scroll bars for a text window
  61.  */
  62. void
  63. TextAdjust (theWindow)
  64.     register WindowPtr theWindow;
  65. {
  66.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  67.     register TEHandle teHdl = infoPtr->item.text.teHdl;
  68.     register ControlHandle scrollHdl = infoPtr->item.text.scroll;
  69.     register WORD scrollHeight, viewLines;
  70.     Rect viewRect, windRect;
  71.     GrafPtr savePort;
  72.     
  73.     GetPort(&savePort);
  74.     SetPort(theWindow);
  75.  
  76.     /* Resize the text view rectangle
  77.      */
  78.     viewRect = theWindow->portRect;
  79.  
  80.     viewRect.left += infoPtr->offset.left;
  81.     viewRect.top += infoPtr->offset.top;
  82.     viewRect.right -= SBAR_WIDTH;
  83.  
  84.     viewLines = (viewRect.bottom - viewRect.top) / (*teHdl)->lineHeight;
  85.     viewRect.bottom = viewRect.top + (viewLines * (*teHdl)->lineHeight);
  86.     (*teHdl)->viewRect = viewRect;
  87.  
  88.     /* Resize the text destination rectangle
  89.      */
  90.     (*teHdl)->destRect.right = viewRect.right;
  91.     TECalText(teHdl);
  92.  
  93.     /* Resize the scroll bars
  94.      */
  95.     windRect = theWindow->portRect;
  96.     scrollHeight = windRect.bottom - windRect.top + 3;
  97.  
  98.     HideControl(scrollHdl);
  99.     MoveControl(scrollHdl, windRect.right - (SBAR_WIDTH - 1), windRect.top - 1);
  100.  
  101.     SizeControl(scrollHdl, SBAR_WIDTH, scrollHeight);
  102.     ShowControl(scrollHdl);
  103.  
  104.     /* Recalculate and go
  105.      */
  106.     TextCalcScroll(theWindow);
  107.     SetPort(savePort);
  108. }
  109.  
  110.  
  111. /* Clear a text window
  112.  */
  113. void
  114. TextWindReset (theWindow)
  115.     register WindowPtr theWindow;
  116. {
  117.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  118.     register TEHandle teHdl = infoPtr->item.text.teHdl;
  119.     register Rect destRect;
  120.     GrafPtr savePort;
  121.     
  122.     GetPort(&savePort);
  123.     SetPort(theWindow);
  124.  
  125.     /* Clear the text handle and selection
  126.      */
  127.     TESetText("\0", (long) 0L, teHdl);
  128.     TESetSelect(0L, 0L, teHdl);
  129.  
  130.     /* Erase the display
  131.      */
  132.     EraseRect(&((*teHdl)->viewRect));
  133.     InvalRect(&((*teHdl)->viewRect));
  134.  
  135.     /* Reinitialize the text destination rectangle, recalc and go
  136.      */
  137.     (*teHdl)->destRect = (*teHdl)->viewRect;
  138.     TECalText(teHdl);
  139.     TextCalcScroll(theWindow);
  140.     SetPort(savePort);
  141. }
  142.  
  143.  
  144. /* TextActivate should be called in response to an activate or deactivate event,
  145.  * and isActive is passed in to determine which of these
  146.  */
  147. void
  148. TextActivate (isActive, theWindow)
  149.     register Boolean isActive;
  150.     register WindowPtr theWindow;
  151. {
  152.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  153.     register TEHandle teHdl = infoPtr->item.text.teHdl;
  154.     GrafPtr savePort;
  155.     
  156.     GetPort(&savePort);
  157.     SetPort(theWindow);
  158.  
  159.     if (isActive) {
  160.         if (teHdl != NULL) {
  161.             TEActivate(teHdl);
  162.  
  163.             if ((*teHdl)->nLines > GetCRefCon(infoPtr->item.text.scroll))
  164.                 HiliteControl(infoPtr->item.text.scroll, 0);
  165.         }
  166.     }
  167.     else {
  168.         if (teHdl != NULL)
  169.             TEDeactivate(teHdl);
  170.  
  171.         HiliteControl(infoPtr->item.text.scroll, 255);
  172.     }
  173.     
  174.     SetPort(savePort);
  175. }
  176.  
  177.  
  178. /* TextUpdate should be called in response to an update event.
  179.  */
  180. void
  181. TextUpdate (theWindow)
  182.     register WindowPtr theWindow;
  183. {
  184.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  185.     register TEHandle teHdl = infoPtr->item.text.teHdl;
  186.     register ControlHandle scrollHdl = infoPtr->item.text.scroll;
  187.     register WORD linesInto = GetCtlValue(scrollHdl);
  188.     register WORD scrollMax = GetCtlMax(scrollHdl);
  189.     Rect viewRect = (*teHdl)->viewRect;
  190.     GrafPtr savePort;
  191.     
  192.     GetPort(&savePort);
  193.     SetPort(theWindow);
  194.  
  195.     /* TEUpdate screws up the last line if it is only a carriage return...
  196.      * so we get to erase the last line before the update.
  197.      */
  198.     if (linesInto == scrollMax) {
  199.         viewRect.top = viewRect.bottom - (2 * (*teHdl)->lineHeight);
  200.         EraseRect(&viewRect);
  201.     }
  202.  
  203.     TEUpdate(&theWindow->portRect, teHdl);
  204.  
  205.     if (theWindow == FrontWindow())
  206.         TEActivate(teHdl);
  207.     else
  208.         TEDeactivate(teHdl);
  209.     
  210.     SetPort(savePort);
  211. }
  212.  
  213.  
  214. /* Write text into the desired debug window
  215.  */
  216. void 
  217. TextPutText (theText, theLen, theWindow)
  218.     register char *theText;
  219.     register LONG theLen;
  220.     register WindowPtr theWindow;
  221. {
  222.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  223.     register TEHandle teHdl = infoPtr->item.text.teHdl;
  224.     GrafPtr savePort;
  225.     
  226.     GetPort(&savePort);
  227.     SetPort(theWindow);
  228.  
  229.     TEInsert(theText, theLen, teHdl);
  230.     TextCalcScroll(theWindow);
  231.  
  232.     SetPort(savePort);
  233. }
  234.  
  235.  
  236. /* Decide how to handle a mouse click in the content of a text window
  237.  */
  238. void
  239. TextContent (theWindow, theMods, thePoint)
  240.     register WindowPtr theWindow;
  241.     register WORD theMods;
  242.     register Point thePoint;
  243. {
  244.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  245.     register TEHandle teHdl = infoPtr->item.text.teHdl;
  246.     register WORD thePart;
  247.     register Boolean isShift = FALSE;
  248.     ControlHandle theControl;
  249.  
  250.     /* Determine if the point is in the text edit view rect
  251.      */
  252.     thePart = FindControl(thePoint, theWindow, &theControl);
  253.  
  254.     switch (thePart) {
  255.     case 0:            /* no control part hit */
  256.         if ((theMods >> 4) & shiftKey) 
  257.             isShift = TRUE;
  258.  
  259.         TEClick(thePoint, isShift, teHdl);
  260.         break;
  261.  
  262.     case inUpButton:
  263.     case inDownButton:
  264.     case inPageUp:
  265.     case inPageDown:
  266.     case inThumb:
  267.         TextDoScroll(theWindow, theControl, thePart, thePoint);
  268.         break;
  269.  
  270.     default:
  271.         TrackControl(theControl, thePoint, (ProcPtr) (-1));
  272.     }
  273. }
  274.  
  275.  
  276. /* Handle a mouse in a window╒s scrollbar
  277.  */
  278. void
  279. TextDoScroll (theWindow, theControl, thePart, thePoint)
  280.     register WindowPtr theWindow;
  281.     register ControlHandle theControl;
  282.     register WORD thePart;
  283.     register Point thePoint;
  284. {
  285.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  286.     register WORD lastVal, deltaVal;
  287.  
  288.     if (thePart == inThumb) {
  289.         lastVal = GetCtlValue(theControl);
  290.         thePart = TrackControl(theControl, thePoint, NULL);
  291.         deltaVal = lastVal - GetCtlValue(theControl);
  292.  
  293.         /* If a change in scroll values exists, scroll that amount
  294.          */
  295.         if (deltaVal != 0)
  296.             TextScroll(0, deltaVal, infoPtr->item.text.teHdl);
  297.     }
  298.     else
  299.         TrackControl(theControl, thePoint, (ProcPtr) TextScrollProc);
  300. }
  301.  
  302.  
  303. /* Called by TrackControl for scrollbar events
  304.  */
  305. pascal void 
  306. TextScrollProc (theControl, thePart)
  307.     register ControlHandle theControl;
  308.     register WORD thePart;
  309. {
  310.     register WindowPtr theWindow = (*theControl)->contrlOwner;
  311.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  312.     register WORD cur_value, cur_max, cur_min, cur_delta;
  313.  
  314.     if (thePart != 0) {
  315.         /* If it was actually in the control
  316.          */
  317.         switch (thePart) {
  318.         case inUpButton:
  319.         case inDownButton:
  320.             /* one line */
  321.             cur_delta = 1;
  322.             break;
  323.  
  324.         case inPageUp:
  325.         case inPageDown:
  326.             /* one page */
  327.             cur_delta = GetCRefCon(theControl);
  328.             break;
  329.         }
  330.  
  331.         if ((thePart == inDownButton) || (thePart == inPageDown))
  332.             cur_delta = -cur_delta;
  333.  
  334.         /* Get value, max and min
  335.          */
  336.         cur_max = GetCtlMax(theControl);
  337.         cur_min = GetCtlMin(theControl);
  338.  
  339.         cur_value = GetCtlValue(theControl);
  340.         cur_delta = cur_value - cur_delta;
  341.         
  342.         if (cur_delta < 0)
  343.             cur_delta = 0;
  344.         else if (cur_delta > cur_max)
  345.             cur_delta = cur_max;
  346.             
  347.         SetCtlValue(theControl, cur_delta);
  348.  
  349.         /* Calculate the real change
  350.          */
  351.         cur_delta = cur_value - cur_delta;      
  352.  
  353.         if (cur_delta != 0)
  354.             TextScroll(0, cur_delta, infoPtr->item.text.teHdl);
  355.     }
  356. }
  357.  
  358.  
  359. /* Recalculate scrollbar values & state
  360.  */
  361. void 
  362. TextCalcScroll (theWindow)
  363.     register WindowPtr theWindow;
  364. {
  365.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  366.     register TEHandle teHdl = infoPtr->item.text.teHdl;
  367.     register ControlHandle scrollHdl = infoPtr->item.text.scroll;
  368.     register WORD linesInto, scrollMax, delta, oldVal;
  369.     register LONG viewLines;
  370.     register Rect viewRect;
  371.     GrafPtr savePort;
  372.     
  373.     GetPort(&savePort);
  374.     SetPort(theWindow);
  375.  
  376.     /* Adjust the viewlines
  377.      */
  378.     viewRect = (*teHdl)->viewRect;
  379.      viewLines = (viewRect.bottom - viewRect.top) / (*teHdl)->lineHeight;
  380.     SetCRefCon(scrollHdl, viewLines);
  381.  
  382.     /* Adjust the min & max
  383.      */
  384.     scrollMax = (*teHdl)->nLines + 1 - viewLines;
  385.  
  386.     if (scrollMax < 0)
  387.         scrollMax = 0;
  388.  
  389.     SetCtlMin(scrollHdl, 0);
  390.     SetCtlMax(scrollHdl, scrollMax);
  391.  
  392.     /* Make the text sticky to the bottom of the viewRect
  393.      */
  394.     linesInto = (viewRect.top - (*teHdl)->destRect.top) / (*teHdl)->lineHeight;
  395.     delta = linesInto - scrollMax;
  396.     
  397.     if ((delta > 0) || (scrollMax == 0)) {
  398.         linesInto = scrollMax;
  399.         oldVal = (*teHdl)->destRect.top;
  400.         (*teHdl)->destRect.top = (*teHdl)->viewRect.top - (linesInto * (*teHdl)->lineHeight);
  401.         TECalText(teHdl);
  402.         
  403.         if (oldVal != (*teHdl)->destRect.top)
  404.             TextUpdate(theWindow);
  405.     }
  406.  
  407.     SetCtlValue(scrollHdl, linesInto);
  408.  
  409.     /* Adjust the hilite
  410.      */
  411.     if (theWindow == FrontWindow()) {
  412.         if (scrollMax > 0)
  413.             HiliteControl(scrollHdl, 0);
  414.         else
  415.             HiliteControl(scrollHdl, 255);
  416.     }
  417. }
  418.  
  419.  
  420. /* Scroll the text manually
  421.  */
  422. void
  423. TextScroll (dh, dv, teHdl)
  424.     register WORD dh;
  425.     register WORD dv;
  426.     register TEHandle teHdl;
  427. {
  428.     /* Calculate the lineHeight
  429.      */
  430.     dv *= (*teHdl)->lineHeight;
  431.  
  432.     /* Adjust the destination rectangle
  433.      */
  434.     (*teHdl)->destRect.left += dh;
  435.     (*teHdl)->destRect.right += dh;
  436.  
  437.     (*teHdl)->destRect.top += dv;
  438.     (*teHdl)->destRect.bottom += dv;
  439.     
  440.     /* Redraw the text
  441.      */
  442.     TextUpdate((*teHdl)->inPort);
  443. }
  444.  
  445.  
  446. /* Scroll the text window to a specific location; changes the scroll bars
  447.  * as well.
  448.  */
  449. void
  450. TextScrollTo (h, v, theWindow)
  451.     register WORD h;
  452.     register WORD v;
  453.     register WindowPtr theWindow;
  454. {
  455.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  456.     register TEHandle teHdl = infoPtr->item.text.teHdl;
  457.     register ControlHandle scrollHdl = infoPtr->item.text.scroll;
  458.     register WORD scrollMax = GetCtlMax(scrollHdl);
  459.  
  460.     /* Pin the max vertical
  461.      */
  462.     if (v > scrollMax)
  463.         v = scrollMax;
  464.  
  465.     /* Adjust the destination rectangle
  466.      */
  467.     (*teHdl)->destRect.left = (*teHdl)->viewRect.left - h;
  468.     (*teHdl)->destRect.top = (*teHdl)->viewRect.top - (v * (*teHdl)->lineHeight);
  469.  
  470.     /* Reset the scroll bar values and redraw the text
  471.      */
  472.     SetCtlValue(scrollHdl, v);
  473.     TextUpdate(theWindow);
  474. }
  475.  
  476.  
  477. /* Scroll the end of the selection range into the view rectangle
  478.  */
  479. void
  480. TextSelView (theWindow)
  481.     register WindowPtr theWindow;
  482. {
  483.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  484.     register TEHandle teHdl = infoPtr->item.text.teHdl;
  485.     register ControlHandle scrollHdl = infoPtr->item.text.scroll;
  486.     register WORD theLine, linesInto, viewLines;
  487.  
  488.     /* Find the line number of the end of selection range
  489.      */
  490.     for (theLine = (*teHdl)->nLines; theLine-- > 0; ) {
  491.         if ((*teHdl)->selEnd >= (*teHdl)->lineStarts[theLine]) {
  492.             /* See if the line is in view
  493.              */
  494.             linesInto = GetCtlValue(scrollHdl);
  495.             viewLines = GetCRefCon(scrollHdl);
  496.             
  497.             /* If not, then let's take a little look-see at it
  498.              */
  499.             if ((theLine < linesInto) || (theLine >= (linesInto + viewLines)))
  500.                 TextScrollTo(0, theLine, theWindow);
  501.             
  502.             TextCalcScroll(theWindow);
  503.             return;
  504.         }
  505.     }
  506. }
  507.