home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Eudora 1.3.1 / source / scrollte.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-16  |  11.2 KB  |  423 lines  |  [TEXT/MPS ]

  1. #define FILE_NUM 48
  2. /* Copyright (c) 1992 by Qualcomm, Inc. */
  3. /* written by Steven Dorner */
  4. #pragma load EUDORA_LOAD
  5. #pragma segment STE
  6.  
  7. #define CanEdit (*ste)->canEdit
  8. #define HBar (*ste)->hBar
  9. #define VBar (*ste)->vBar
  10. #define TE (*ste)->te
  11. #define EncloseR (*ste)->encloseR
  12. #define DontFrame (*ste)->dontFrame
  13. #define GrowBox (*ste)->growBox
  14. /************************************************************************
  15.  * Handling for scrolling TE fields within a window
  16.  ************************************************************************/
  17.     void GetSTERects(STEHandle ste,Rect *enclosingRect,Rect *viewRect);
  18.     pascal Boolean STEClikLoop(void);
  19.     void STEScrollWithBars(STEHandle ste,short h,short v);
  20.  
  21. /************************************************************************
  22.  * NewSTE - create a new one
  23.  ************************************************************************/
  24. STEHandle NewSTE(MyWindowPtr win,Rect *enclosingRect,Boolean hBar,Boolean vBar,Boolean canEdit)
  25. {
  26.     STEHandle ste;
  27.     Handle grumble;
  28.     SAVE_PORT;
  29.     
  30.     SetPort(win);
  31.     
  32.     /*
  33.      * the record itself
  34.      */
  35.     if (!(ste = NewZH(STE))) goto fail;
  36.     if (!(grumble = TENew(enclosingRect,enclosingRect))) goto fail;
  37.     TE = grumble;
  38.     CanEdit = canEdit;
  39.     (*TE)->txFont = FontID;
  40.     (*TE)->txSize = FontSize;
  41.     (*TE)->fontAscent = FontAscent;
  42.     (*TE)->lineHeight = FontLead;
  43.     
  44.     TEAutoView(True,TE);
  45.     if (hBar || vBar)
  46.         (*TE)->clikLoop = STEClikLoop;
  47.     
  48.     /*
  49.      * scroll bars
  50.      */
  51.     if (hBar)
  52.     {
  53.         if (!(grumble = GetNewControl(SCROLL_CNTL,win))) goto fail;
  54.         HBar = grumble;
  55.         SetCtlAction(HBar,ScrollAction);
  56.     }
  57.     if (vBar)
  58.     {
  59.         if (!(grumble = GetNewControl(SCROLL_CNTL,win))) goto fail;
  60.         VBar = grumble;
  61.         SetCtlAction(VBar,ScrollAction);
  62.     }
  63.     
  64.     /*
  65.      * size properly and we're done
  66.      */
  67.     if (enclosingRect) ResizeSTE(ste,enclosingRect);
  68.     REST_PORT;
  69.     return(ste);
  70.  
  71.     fail:
  72.         REST_PORT;
  73.         STEDispose(ste);
  74.         return(nil);
  75. }
  76.     
  77. #pragma segment Main
  78. /************************************************************************
  79.  * STEDispose - so long
  80.  ************************************************************************/
  81. void STEDispose(STEHandle ste)
  82. {
  83.     if (ste)
  84.     {
  85.         if (HBar) DisposeControl(HBar);
  86.         if (VBar) DisposeControl(VBar);
  87.         if (TE) TEDispose(TE);
  88.         DisposeHandle(ste);
  89.     }
  90. }
  91. #pragma segment STE
  92. /************************************************************************
  93.  * STEClick - handle a mouse click.  Returns True if event was handled.
  94.  ************************************************************************/
  95. Boolean STEClick(STEHandle ste,EventRecord *event)
  96. {
  97.     Point pt;
  98.     MyWindowPtr win = (*TE)->inPort;
  99.     Rect vR,eR;
  100.     
  101.     GetSTERects(ste,&eR,&vR);
  102.     
  103.     pt = event->where; GlobalToLocal(&pt);
  104.     if (!PtInRect(pt,&eR)) return(False);
  105.     if (HandleControl(pt,win))
  106.         ;
  107.     else if (PtInRect(pt,&vR))
  108.     {
  109.         TEClick(pt,(event->modifiers&shiftKey)!=0,TE);
  110.         if (ClickType==Triple) TESelPara(TE);
  111.         win->hasSelection = (*TE)->selStart != (*TE)->selEnd;
  112.         STESetScrolls(ste);
  113.     }
  114.     return(True);
  115. }
  116.  
  117. /************************************************************************
  118.  * ResizeSTE - size it properly, or handle scrolling, etc.
  119.  ************************************************************************/
  120. void ResizeSTE(STEHandle ste,Rect *newRect)
  121. {
  122.     Rect encR, viewR;
  123.     short extreme;
  124.     short offset;
  125.     short topOffset;
  126.     Boolean vis;
  127.     short h,v;
  128.  
  129.     if (newRect)
  130.     {
  131.         vis = ((WindowPeek)(*TE)->inPort)->visible;
  132.         /*
  133.          * invalidate the old rectangle
  134.          */
  135.         GetSTERects(ste,&encR,&viewR);
  136.         InvalRect(&encR);
  137.                 
  138.         /*
  139.          * recalculate stuff
  140.          */
  141.         if (vis) topOffset = TopOffset(TE);
  142.         EncloseR = encR = *newRect;/* new scroll bar locations */
  143.         if (HBar) encR.bottom -= GROW_SIZE;
  144.         if (VBar)
  145.         {
  146.             encR.right -= GROW_SIZE;
  147.             extreme = encR.bottom;
  148.             if (!HBar && GrowBox) extreme -= GROW_SIZE-1;
  149.             MoveMyCntl((*TE)->inPort,VBar,encR.right-1,encR.top,
  150.                                     GROW_SIZE+1,extreme-encR.top);
  151.         }
  152.         if (HBar)
  153.         {
  154.             extreme = encR.right;
  155.             if (!VBar && GrowBox) extreme -= GROW_SIZE;
  156.             MoveMyCntl((*TE)->inPort,HBar,encR.left,encR.bottom-1,
  157.                                                     extreme-encR.left,GROW_SIZE+1);
  158.         }
  159.  
  160.         InsetRect(&encR,TE_HMARGIN,TE_VMARGIN);        /* and the edit box itself */
  161.         offset = (encR.bottom-encR.top)%(*TE)->lineHeight;
  162.         encR.top += offset/2;
  163.         encR.bottom -= offset-offset/2;
  164.         offset = (*TE)->viewRect.top-encR.top;    /* amount of adjustment */
  165.         (*TE)->viewRect = encR;
  166.         (*TE)->destRect.left = encR.left;
  167.         (*TE)->destRect.right = encR.right;
  168.         if (!vis)
  169.         {
  170.             (*TE)->destRect.top = encR.top;
  171.             (*TE)->destRect.bottom = encR.bottom;
  172.         }
  173.         else (*TE)->destRect.top -= offset;        /* keep view and dest in synch */
  174.         NoScrollTECalText(TE);
  175.         INVAL_RECT(&(*TE)->viewRect);
  176.         if (vis) MakeTopOffset(TE,topOffset);
  177.     }
  178.     
  179.     /*
  180.      * take care of the scroll bars
  181.      */
  182.     GetSTERects(ste,&encR,&viewR);
  183.     h=v=0;
  184.     if (VBar)
  185.     {
  186.         BarMax(VBar,CountTeLines(TE),viewR.bottom-viewR.top,FontLead);
  187.         v = RoundDiv(viewR.top-(*TE)->destRect.top,FontLead);
  188.         if (v>GetCtlMax(VBar)) v = v-GetCtlMax(VBar);
  189.         else v = 0;
  190.     }
  191.     if (HBar)
  192.     {
  193.         BarMax(HBar,TEMaxLine(TE),viewR.right-viewR.left,FontWidth);
  194.         h = RoundDiv(viewR.left-(*TE)->destRect.left,FontWidth);
  195.         if (h>GetCtlMax(HBar)) h = h-GetCtlMax(HBar);
  196.         else h = 0;
  197.     }
  198.     STEScroll(ste,h,v);
  199.     STESetScrolls(ste);
  200. }
  201.  
  202. /************************************************************************
  203.  * GetSTERects - extract the enclosing and view rectangles
  204.  ************************************************************************/
  205. void GetSTERects(STEHandle ste,Rect *enclosingRect,Rect *viewRect)
  206. {
  207.     *enclosingRect = EncloseR;
  208.     *viewRect = (*TE)->viewRect;
  209. }
  210.  
  211. /************************************************************************
  212.  * STESetText - set the text of a scrolling area
  213.  ************************************************************************/
  214. void STESetText(UPtr text,short length,STEHandle ste)
  215. {
  216.     SAVE_PORT;
  217.     SetPort((*TE)->inPort);
  218.     INVAL_RECT(&(*TE)->viewRect);
  219.     TESetText("",0,TE);
  220.     STEScrollWithBars(ste,INFINITY,INFINITY);
  221.     TESetText(text,length,TE);
  222.     ResizeSTE(ste,nil);
  223.     REST_PORT;
  224. }
  225.  
  226. /************************************************************************
  227.  * STEAppendText - add to the text of a scrolling area
  228.  ************************************************************************/
  229. void STEAppendText(UPtr text,short length,STEHandle ste)
  230. {
  231.     SAVE_PORT;
  232.     SetPort((*TE)->inPort);
  233.     TESetSelect(INFINITY,INFINITY,TE);
  234.     TEInsert(text,length,TE);
  235.     ResizeSTE(ste,nil);
  236.     REST_PORT;
  237. }
  238.  
  239. /************************************************************************
  240.  * STEInstallText - install a whole new text in a scrolling area
  241.  ************************************************************************/
  242. void STEInstallText(Handle text,STEHandle ste)
  243. {
  244.     SAVE_PORT;
  245.     SetPort((*TE)->inPort);
  246.     DisposeHandle((*TE)->hText);
  247.     (*TE)->hText = text;
  248.     (*TE)->teLength = GetHandleSize(text);
  249.     TECalText(TE);
  250.     ResizeSTE(ste,nil);
  251.     INVAL_RECT(&(*TE)->viewRect);
  252.     REST_PORT;
  253. }
  254.  
  255. /************************************************************************
  256.  * STECursor - set the cursor properly
  257.  ************************************************************************/
  258. Boolean STECursor(STEHandle ste)
  259. {
  260.     Point pt;
  261.     Rect eR, vR;
  262.     Boolean found=False;
  263.     
  264.     GetMouse(&pt);
  265.     GetSTERects(ste,&eR,&vR);
  266.     if (CursorInRect(pt,eR,MouseRgn))
  267.     {
  268.         if (CursorInRect(pt,vR,MouseRgn))
  269.             SetMyCursor(iBeamCursor);
  270.         else
  271.             SetMyCursor(arrowCursor);
  272.         found = True;
  273.     }
  274.     else
  275.         SetMyCursor(arrowCursor);
  276.     return(found);
  277. }
  278.  
  279. /************************************************************************
  280.  * STEShowInsert - show the insertion point
  281.  ************************************************************************/
  282. void STEShowInsert(STEHandle ste)
  283. {
  284.     Rect r = (*TE)->viewRect;
  285.     short dv;
  286.     if (dv=TEInsertDelta(TE,&r,InsertAny))
  287.         STEScrollWithBars(ste,0,dv);
  288.     STESetScrolls(ste);
  289. }
  290.  
  291. /************************************************************************
  292.  * STEUpdate - update an STE
  293.  ************************************************************************/
  294. void STEUpdate(STEHandle ste)
  295. {
  296.     Rect encR,viewR;
  297.     
  298.     GetSTERects(ste,&encR,&viewR);
  299.     if (!DontFrame)
  300.     {
  301.         if (HBar) encR.bottom -= GROW_SIZE;
  302.         if (VBar) encR.right -= GROW_SIZE;
  303.         FrameRect(&encR);
  304.     }
  305.     TEUpdate(&viewR,TE);
  306. }
  307.  
  308. /************************************************************************
  309.  * STESetScrolls - set the scroll bars according to how the field is scrolled
  310.  ************************************************************************/
  311. void STESetScrolls(STEHandle ste)
  312. {
  313.     Rect dest,view;
  314.     short v;
  315.     GetSTERects(ste,&dest,&view);
  316.     dest = (*TE)->destRect;
  317.     if (HBar)
  318.     {
  319.         v = RoundDiv(view.left - dest.left,FontWidth);
  320.         SetCtlValue(HBar,MAX(0,v));
  321.     }
  322.     if (VBar)
  323.     {
  324.         v = RoundDiv(view.top - dest.top,FontLead);
  325.         SetCtlValue(VBar,MAX(0,v));
  326.     }
  327. }
  328.  
  329. /************************************************************************
  330.  * STEClikLoop - keep the scroll bars up-to-date
  331.  ************************************************************************/
  332. pascal Boolean STEClikLoop(void)
  333. {
  334.     MyWindowPtr win = FrontWindow();
  335.     static lastTicks;
  336.     
  337.     if (win && TickCount()-lastTicks>3)
  338.     if (win)
  339.     {
  340.         STEHandle ste = ((MyWindowPtr)(FrontWindow()))->ste;
  341.         Point pt;
  342.         Rect viewR,encR;
  343.         if (ClickType==Triple) TESelPara(TE);
  344.         GetSTERects(ste,&encR,&viewR);
  345.         GetMouse(&pt);
  346.         if (pt.v < viewR.top) pt.v = viewR.top-pt.v;
  347.         else if (pt.v > viewR.bottom) pt.v = viewR.bottom-pt.v;
  348.         else pt.v = 0;
  349.         if (pt.h < viewR.left) pt.h = viewR.left-pt.h;
  350.         else if (pt.h > viewR.right) pt.h = viewR.right-pt.h;
  351.         else pt.h = 0;
  352.         if (pt.h || pt.v)
  353.         {
  354.           pt.h = RoundDiv(pt.h,win->hPitch);
  355.             pt.v = RoundDiv(pt.v,win->vPitch);
  356.           STEScrollWithBars(ste,pt.h,pt.v);
  357.         }
  358.     }
  359.     return(True);
  360. }
  361.  
  362. /************************************************************************
  363.  * STEScroll - scroll the area
  364.  ************************************************************************/
  365. void STEScroll(STEHandle ste,short h,short v)
  366. {
  367.   MyWindowPtr win = (*TE)->inPort;
  368.     TEScroll(win->hPitch*h,win->vPitch*v,TE);
  369. }
  370.  
  371.  
  372. /************************************************************************
  373.  * STEScrollWithBars - change the values of the scroll bars, and scroll
  374.  ************************************************************************/
  375. void STEScrollWithBars(STEHandle ste,short h,short v)
  376. {
  377.   MyWindowPtr win = (*TE)->inPort;
  378.     RgnHandle oldClip = win->qWindow.port.clipRgn;
  379.     win->qWindow.port.clipRgn = NewRgn();
  380.     InfiniteClip(win);
  381.     h = HBar ? -IncMyCntl(HBar,-h) : 0;
  382.     v = VBar ? -IncMyCntl(VBar,-v) : 0;
  383.     DisposeRgn(win->qWindow.port.clipRgn);
  384.     win->qWindow.port.clipRgn = oldClip;
  385.     STEScroll(ste,h,v);
  386. }
  387.  
  388. /************************************************************************
  389.  * STETextChanged - the text has changed in a scrolling window
  390.  ************************************************************************/
  391. void STETextChanged(STEHandle ste)
  392. {
  393.     ResizeSTE(ste,nil);
  394.     STEShowInsert(ste);
  395. }
  396.  
  397. /************************************************************************
  398.  * STEApp1 - handle the special keys
  399.  ************************************************************************/
  400. void STEApp1(STEHandle ste,EventRecord *event)
  401. {
  402.     Rect encR,viewR;
  403.     short page;
  404.     
  405.     GetSTERects(ste,&encR,&viewR);
  406.     page = RoundDiv(viewR.bottom-viewR.top,FontLead)-1;
  407.     
  408.     switch(event->message & charCodeMask)
  409.     {
  410.         case homeChar:
  411.             STEScrollWithBars(ste,INFINITY,INFINITY);
  412.             break;
  413.         case endChar:
  414.             STEScrollWithBars(ste,0,-INFINITY);
  415.             break;
  416.         case pageUpChar:
  417.             STEScrollWithBars(ste,0,page);
  418.             break;
  419.         case pageDownChar:
  420.             STEScrollWithBars(ste,0,-page);
  421.             break;
  422.     }
  423. }