home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / EMBL Search / Sources / click.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-04  |  9.3 KB  |  362 lines  |  [TEXT/KAHL]

  1. /*
  2. *********************************************************************
  3. *    
  4. *    Click.c
  5. *    Mouseclicks in window content region
  6. *
  7. *    Rainer Fuchs
  8. *    EMBL Data Library
  9. *    Postfach 10.2209
  10. *    D-6900 Heidelberg, FRG
  11. *    E-mail: fuchs@embl-heidelberg.de
  12. *
  13. *    Copyright © 1992 EMBL Data Library
  14. *        
  15. **********************************************************************
  16. *    
  17. */ 
  18.  
  19. #include <string.h>
  20. #include <stdio.h>
  21.  
  22. #include "EMBL-Search.h"
  23. #include "EMBL-Search.rsrc.h"
  24.  
  25. /*
  26. ******************************* Prototypes ****************************
  27. */
  28.  
  29. #include "click.h"
  30. #include "util.h"
  31. #include "results.h"
  32. #include "hitstorage.h"
  33. #include "sequence.h"
  34.  
  35. static void ResDragScroll(WindowPtr wPtr, ControlHandle theControl, short scrollAmt);
  36. static short GetClickRow(WDPtr wdp, Rect *viewRectPtr, Point *where);
  37. static Boolean IsResDoubleClick(EventRecord *eventPtr, Rect *viewRectPtr, WDPtr wdp);
  38.  
  39.  
  40. /*
  41. ********************************* Globals *****************************
  42. */
  43.  
  44. extern FONTINFO    fMonaco;
  45. extern ClickInfo    gLastClick;
  46.  
  47.  
  48. /**************************************
  49. *    Handle clicks in content region of sequence window
  50. */
  51.  
  52. void DoSeqContentClick(EventRecord *eventPtr, Rect *viewRectPtr, WDPtr wdp)
  53. {
  54.     if( wdp == NULL || ((WindowPeek)wdp)->windowKind != seqW )
  55.         return;
  56.         
  57.     /* we don't do anything, but we could allow text selection here */
  58. }
  59.  
  60. /**************************************
  61. *    Handle clicks in content region of result window
  62. */
  63.  
  64. void DoResContentClick(EventRecord *eventPtr,Rect *viewRectPtr,WDPtr wdp)
  65. {
  66.     register     short    i;
  67.     register     short    bufPos,newBufPos,anchor;
  68.     short            firstSelectRow,lastSelectRow,sel;
  69.     ResultHdl    resHdl;
  70.     HitlistHdl    hlHdl;
  71.     short         oldStatus,newStatus;
  72.     Point            where;
  73.     SignedByte    oldRState;
  74.     short            screenTop,visLines;
  75.     GrafPtr        savePort;
  76.  
  77.     if( wdp == NULL || ((WindowPeek)wdp)->windowKind != resW )
  78.         return;
  79.         
  80.     savePort = ChangePort((GrafPtr)wdp);
  81.     where=eventPtr->where;
  82.     GlobalToLocal(&where);
  83.     
  84.     resHdl = (ResultHdl)(wdp->userHandle);
  85.     hlHdl = (**resHdl).hlHdl;
  86.  
  87.     visLines = (viewRectPtr->bottom - viewRectPtr->top) / fMonaco.height;
  88.     
  89.     /* find current row */
  90.     bufPos = GetClickRow(wdp,viewRectPtr,&where);
  91.     if( bufPos >= (**resHdl).nhits ) {
  92.     
  93.         /* deselect all */
  94.         oldRState = MyHLock((Handle)resHdl);
  95.         for( i = 0; i < (**resHdl).nhits; i++)
  96.             SelectDraw(wdp,i,FALSE);
  97.         HSetState((Handle)resHdl,oldRState);
  98.         
  99.         /* update header */
  100.         DrawResHeader(wdp, resHdl);
  101.         SetPort(savePort);
  102.         return;
  103.     }
  104.  
  105.     /* Double click ? */
  106.     if( IsResDoubleClick(eventPtr, viewRectPtr, wdp) ) {
  107.         oldRState = MyHLock((Handle)resHdl);
  108.         for(i=0;i < (**resHdl).nhits; i++) {
  109.             if( GetSelectState(hlHdl,i) ) {
  110.                 if( !NewSequenceWindow(resHdl,i) )
  111.                     break;
  112.             }
  113.         }
  114.         HSetState((Handle)resHdl,oldRState);
  115.         SetPort(savePort);
  116.         return;
  117.     }
  118.  
  119.     /* Handle clicks differently depending on modifier keys pressed */
  120.     
  121.     /* no modifiers */
  122.     if( !(eventPtr->modifiers & shiftKey) &&
  123.         !(eventPtr->modifiers & cmdKey) ) { 
  124.         
  125.         /* deselect all */
  126.         oldRState = MyHLock((Handle)resHdl);
  127.         for( i = 0; i < (**resHdl).nhits; i++)
  128.             SelectDraw(wdp,i,FALSE);
  129.         HSetState((Handle)resHdl,oldRState);
  130.             
  131.         /* select and update header */
  132.         SelectDraw(wdp, bufPos, TRUE);
  133.         DrawResHeader(wdp, resHdl);
  134.     
  135. /*        while( StillDown() ) {*/
  136. /*            GetMouse(&where);    *//* GetMouse returns local coordinates *//**/
  137. /*            if (PtInRect(where,viewRectPtr) ) {*/
  138. /*                newBufPos = GetClickRow(wdp,viewRectPtr,&where);*/
  139. /*                if ( newBufPos != bufPos ) {    *//* if moved *//**/
  140. /*                    *//* deselect old row and select new row *//**/
  141. /*                    if( bufPos < (**resHdl).nhits && newBufPos < (**resHdl).nhits ) {*/
  142. /*                        SelectDraw(wdp,bufPos, FALSE);*/
  143. /*                        SelectDraw(wdp,newBufPos, TRUE);*/
  144. /*                        DrawResHeader(wdp, resHdl);*/
  145. /*                    }*/
  146. /*                    bufPos = newBufPos;*/
  147. /*                }*/
  148. /*            }*/
  149. /*        }*/
  150.     }
  151.     
  152.     /* command key */
  153.     else if ( eventPtr->modifiers & cmdKey ) {
  154.         /* Get status of selected cell */
  155.         oldStatus = GetSelectState(hlHdl,bufPos);
  156.         newStatus = !oldStatus;
  157.         
  158.         /* select and update header */
  159.         SelectDraw(wdp, bufPos, newStatus);
  160.         DrawResHeader(wdp, resHdl);
  161.         
  162.         while( StillDown() ) {
  163.             screenTop = GetCtlValue(wdp->vScroll);    /* first hit on screen */
  164.             GetMouse(&where);    /* GetMouse returns local coordinates */
  165.             newBufPos = GetClickRow(wdp,viewRectPtr,&where);
  166.             if(newBufPos < screenTop)
  167.                 newBufPos = screenTop;
  168.             else if(newBufPos >= screenTop + visLines)
  169.                 newBufPos = screenTop + visLines -1;
  170.                 
  171.             if(newBufPos >= (**resHdl).nhits)
  172.                 newBufPos = (**resHdl).nhits - 1;
  173.             else if(newBufPos < 0)
  174.                 newBufPos = 0;
  175.                 
  176.             /* select new row(s) */
  177.             if(newBufPos < bufPos) {
  178.                 for(i = newBufPos; i<= bufPos; ++i) {
  179.                     SelectDraw(wdp,i, newStatus);
  180.                 }
  181.             
  182.                 DrawResHeader(wdp, resHdl);
  183.                 bufPos = newBufPos;
  184.             }
  185.             if(newBufPos > bufPos) {
  186.                 for(i = bufPos; i<= newBufPos; ++i) {
  187.                     SelectDraw(wdp,i, newStatus);
  188.                 }
  189.             
  190.                 DrawResHeader(wdp, resHdl);
  191.                 bufPos = newBufPos;
  192.             }
  193.             
  194.             if(newBufPos < (**resHdl).nhits - 1 && where.v > viewRectPtr->bottom) {
  195.                 SelectDraw(wdp,bufPos = newBufPos + 1,newStatus);
  196.                 ResDragScroll((WindowPtr)wdp,(ControlHandle)wdp->vScroll,1);
  197.                 DrawResHeader(wdp, resHdl);
  198.             }
  199.             else if(newBufPos > 0 && where.v < viewRectPtr->top) {
  200.                 SelectDraw(wdp,bufPos = newBufPos - 1,newStatus);
  201.                 ResDragScroll((WindowPtr)wdp,(ControlHandle)wdp->vScroll,-1);
  202.                 DrawResHeader(wdp, resHdl);
  203.             }
  204.         }
  205.     }
  206.     
  207.     /* shift key */
  208.     else if ( eventPtr->modifiers & shiftKey ) {
  209.         /* find first and last selected row */
  210.         firstSelectRow = lastSelectRow = -1;
  211.         oldRState = MyHLock((Handle)resHdl);
  212.         for( i = sel = 0; i < (**resHdl).nhits && sel < (**resHdl).nsel; ++i)
  213.             if( GetSelectState(hlHdl,i) ) {
  214.                 sel++;
  215.                 if (sel == 1)
  216.                     firstSelectRow = i;
  217.                 if (sel == (**resHdl).nsel)
  218.                     lastSelectRow = i;
  219.             }
  220.         HSetState((Handle)resHdl,oldRState);
  221.         
  222.         if( firstSelectRow == -1)
  223.             firstSelectRow = bufPos;    
  224.         if( lastSelectRow == -1) {
  225.             if(bufPos > firstSelectRow)
  226.                 lastSelectRow = bufPos;
  227.             else
  228.                 lastSelectRow = firstSelectRow;
  229.         }
  230.             
  231.         if( bufPos >= firstSelectRow ) {
  232.             for(i = firstSelectRow; i <= bufPos; ++i)
  233.                 SelectDraw(wdp,i,TRUE);
  234.             for(i = bufPos+1; i<=lastSelectRow; ++i)
  235.                 SelectDraw(wdp,i,FALSE);
  236.             anchor = firstSelectRow;
  237.         }
  238.         else {
  239.             for(i = bufPos; i <= lastSelectRow; ++i)
  240.                 SelectDraw(wdp,i,TRUE);
  241.             anchor = lastSelectRow;
  242.         }
  243.         DrawResHeader(wdp, resHdl);
  244.  
  245.     /* I wonder whether there is some bug in StillDown() ?!? If I hold the mouse button
  246.         down and move up and down for a while, sometimes this procedure breaks out of the
  247.         while (StillDown()) loop...
  248.     */
  249.         while( StillDown() ) {
  250.             screenTop = GetCtlValue(wdp->vScroll);    /* first hit on screen */
  251.             GetMouse(&where);    /* GetMouse returns local coordinates */
  252.             newBufPos = GetClickRow(wdp,viewRectPtr,&where);
  253.             if(newBufPos < screenTop)
  254.                 newBufPos = screenTop;
  255.             else if(newBufPos >= screenTop + visLines)
  256.                 newBufPos = screenTop + visLines -1;
  257.                 
  258.             if(newBufPos >= (**resHdl).nhits)
  259.                 newBufPos = (**resHdl).nhits - 1;
  260.             else if(newBufPos < 0)
  261.                 newBufPos = 0;
  262.                 
  263.             if( newBufPos < bufPos ) {
  264.                 for(i = bufPos; i>= newBufPos ; --i) {
  265.                     if( i <= anchor || i == newBufPos )
  266.                         SelectDraw(wdp,i,TRUE);
  267.                     else
  268.                         SelectDraw(wdp,i, FALSE);
  269.                 }
  270.  
  271.                 DrawResHeader(wdp, resHdl);
  272.                 bufPos = newBufPos;
  273.             }
  274.             
  275.             if( newBufPos > bufPos ) {
  276.                 for(i = bufPos; i<= newBufPos; ++i) {
  277.                     if( i >= anchor || i == newBufPos )
  278.                         SelectDraw(wdp,i,TRUE);
  279.                     else
  280.                         SelectDraw(wdp,i, FALSE);
  281.                 }
  282.                 
  283.                 DrawResHeader(wdp, resHdl);
  284.                 bufPos = newBufPos;
  285.             }
  286.             
  287.             if(newBufPos < (**resHdl).nhits - 1 && where.v > viewRectPtr->bottom) {
  288.                 SelectDraw(wdp,bufPos = newBufPos + 1,TRUE);
  289.                 ResDragScroll((WindowPtr)wdp,(ControlHandle)wdp->vScroll,1);
  290.                 DrawResHeader(wdp, resHdl);
  291.             }
  292.             else if(newBufPos > 0 && where.v < viewRectPtr->top) {
  293.                 SelectDraw(wdp,bufPos = newBufPos - 1,TRUE);
  294.                 ResDragScroll((WindowPtr)wdp,(ControlHandle)wdp->vScroll,-1);
  295.                 DrawResHeader(wdp, resHdl);
  296.             }
  297.         }
  298.     }
  299.     SetPort(savePort);
  300. }
  301.  
  302. /**************************************
  303. *    Update result window when user drag-scrolls
  304. */
  305.  
  306. static void ResDragScroll(WindowPtr wPtr, ControlHandle theControl, short scrollAmt)
  307. {
  308.     short            oldValue,newValue;
  309.     short            max=GetCtlMax(theControl);
  310.     
  311.     oldValue=GetCtlValue(theControl);
  312.     newValue=oldValue+scrollAmt;
  313.     /* limit check */
  314.     if(newValue < 0) newValue=0;
  315.     if(newValue > max) newValue=max;
  316.             
  317.     SetCtlValue( theControl, newValue );
  318.     AdjustResText(wPtr,oldValue,newValue,vertBar);
  319. }
  320.  
  321.  
  322. /**************************************
  323. *    Find line in result buffer corresponding to screen position where click occurred
  324. *    Return value:    line offset in result buffer
  325. */
  326.  
  327. static short GetClickRow(WDPtr wdp, Rect *viewRectPtr,Point *where)
  328. {
  329.     short screenRow,hitPos;
  330.     
  331.     hitPos = GetCtlValue(wdp->vScroll);    /* first hit on screen */
  332.     screenRow = (where->v - viewRectPtr->top) / fMonaco.height;
  333.     return(hitPos + screenRow);
  334. }
  335.  
  336.  
  337. static Boolean IsResDoubleClick(EventRecord *eventPtr, Rect *viewRectPtr, WDPtr wdp)
  338. {
  339.     Point where1,where2;
  340.     GrafPtr savePort;
  341.     
  342.     if((WindowPtr)wdp != gLastClick.wPtr)
  343.         return(FALSE);
  344.         
  345.     if(eventPtr->when-gLastClick.when > GetDblTime())
  346.         return(FALSE);
  347.  
  348.     savePort = ChangePort((GrafPtr)wdp);
  349.     where1 = eventPtr->where;
  350.     GlobalToLocal(&where1);
  351.     where2 = gLastClick.where;
  352.     GlobalToLocal(&where2);
  353.     SetPort(savePort);
  354.     
  355.     if(GetClickRow(wdp,viewRectPtr,&where1) ==
  356.         GetClickRow(wdp,viewRectPtr,&where2))
  357.         return(TRUE);
  358.     
  359.     return(FALSE);
  360. }
  361.  
  362.