home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / CSSRC / SDMOUFRM.C < prev    next >
C/C++ Source or Header  |  1990-12-19  |  11KB  |  362 lines

  1. /*
  2.     sdmoufrm.c
  3.  
  4.     % sedmou_Framer
  5.  
  6.     12/09/89  Re-created by Ted.
  7.  
  8.     A mousehandler for framer menus.
  9.  
  10.     C-scape 3.2
  11.     Copyright (c) 1988, 1989 by Oakland Group, Inc.
  12.     ALL RIGHTS RESERVED.
  13.  
  14.     Revision History:
  15.     -----------------
  16.      1/24/90 ted    Fixed a lot of stuff to get more SAA-like.
  17.      1/28/90 ted    Added fixes for when borders pass msgs through.
  18.      2/14/90 ted    Added MEV_STARTCUR check when setting framer flag.
  19.      3/03/90 ted/pmcm Fixed ufunc/child popup return case.
  20.      3/03/90 ted/pmcm Added support for sed_FindField -2 return in case of protected fields.
  21.      3/28/90 jmd    ansi-fied
  22.      4/08/90 ted    Fixed pulldown bug pmcm and I made on 3/3/90 when we fixed the ufunc rtn case.
  23.      5/12/90 jmd    mouse handlers now return ints
  24.      8/13/90 ted    Changed references from sed_SetMouseCode to kb_Stuff.
  25.      8/13/90 ted    Modified framer bit test to allow sub-pulldowns.
  26.      8/29/90 ted    Reconstructed to have more SAA-like mouse behavior.
  27.      9/11/90 ted    Fixed null-mev bug in 'inside' assignment.
  28.      9/15/90 ted    Added missing break in MEV_STARTCUR case.
  29.      9/23/90 ted    Overhauled to make 'demofram' still work.
  30.     10/04/90 ted    Fixed ufunc popmenu vacuum click bug.
  31.     10/16/90 ted    fixed framer test loop so embedded framers will work.
  32.     12/04/90 ted    checked for when CurrentWin is NULL.
  33.     12/19/90 ted/jdc changed outside startevent/event case to check mev_IsFake.
  34. */
  35.  
  36. #include <stdio.h>
  37. #include "cscape.h"
  38. #include "oaktag.h"                /* For ID in bob_IsUfunc */
  39. #include "msys.h"
  40.  
  41. #include "scancode.h"        /* for MOU codes */
  42. /* -------------------------------------------------------------------------- */
  43.  
  44. int sedmou_Framer(sed_type sed, int msg, mev_struct *mev)
  45. /*
  46.     Messages a mouse handler receives when its window is current
  47.     MEV_REQUEST            current; someone else wants to be current
  48.     MEV_STARTEVENT        current, mouse entered
  49.     MEV_EVENT            current, event in win
  50.     MEV_ENDEVENT        current, mouse left
  51.     Messages a mouse handler receives when its window is not current
  52.     MEV_STARTOFFER        not current, mouse entered
  53.     MEV_OFFER            not current, event in win
  54.     MEV_ENDOFFER        not current, mouse left
  55. */
  56. {
  57.     win_type parent;
  58.     boolean inside;
  59.  
  60.     /* The first time this happens we need to set the framer true */
  61.     if (msg == MEV_STARTOFFER || msg == MEV_STARTCUR) {
  62.         /* If we're the first here, we're the top framer, so we set a bit so our
  63.             kids won't think they're it. */
  64.  
  65.         if (!msys_IsFramer(sed)) {
  66.             parent = sed;
  67.             for (;;) {
  68.                 if ((parent = bob_GetParent(parent)) == NULL) {
  69.                     msys_SetFramer(sed, TRUE);
  70.                     break;
  71.                 }
  72.                 if (msys_IsFramer(parent)) {
  73.                     break;
  74.                 }
  75.             }
  76.         }
  77.     }
  78.  
  79.     if (msys_IsFramer(sed)) {
  80.  
  81.         if (mev != NULL) {    /* not STARTCUR or STOPCUR message */
  82.             inside = (mev_GetX(mev) >= 0 && mev_GetY(mev) >= 0 &&
  83.                       mev_GetX(mev) < win_GetPixWidth(sed) && 
  84.                       mev_GetY(mev) < win_GetPixHeight(sed));
  85.         }
  86.  
  87.         /* Use sedmou_Drag behavior for framer top menu, except special cases. */
  88.         if (inside || msg == MEV_REQUEST ||
  89.                 msg == MEV_STARTCUR || msg == MEV_STOPCUR) {
  90.             switch (msg) {
  91.             case MEV_STARTCUR:
  92.                 /* Trap all mouse events while we're the current window */
  93.                 disp_TrapMouse(sed);
  94.                 break;
  95.             case MEV_STOPCUR:
  96.                 break;
  97.  
  98.             case MEV_STARTOFFER:           /* we're not the current window */
  99.                 win_SetDebounced(sed, mev_IsButtonDown(mev));
  100.             case MEV_OFFER:
  101.             {
  102.                 ocbox mbox;
  103.                 int fld;
  104.  
  105.                 /* If current window is a child of ours, don't accept offer
  106.                     but return a code to exit the child */
  107.                 parent = disp_GetCurrentWin();
  108.                 for (;;) {
  109.                     if (parent == NULL) {
  110.                         return(sedmou_Drag(sed, msg, mev));
  111.                     }
  112.                     parent = bob_GetParent(parent);
  113.  
  114.                     if (parent == sed) {
  115.                         break;
  116.                     }
  117.                 }
  118.                 if (!mev_IsFake()) {
  119.                     if (mev_IsButtonDown(mev)) {
  120.  
  121.                         if (win_GetDebounced(sed)) {
  122.                             mbox.toprow = mbox.botrow = mev_GetRow(mev) + sed_GetYoffset(sed);
  123.                             mbox.leftcol = mbox.rightcol = mev_GetCol(mev) + sed_GetXoffset(sed);
  124.  
  125.                             /* sed_FindField finds the best field in the given box */ 
  126.                             fld = sed_FindField(sed, &mbox, OAK_DOWN);
  127.                         }
  128.  
  129.                         /* Exit dropdown for click or new field in framer menu */
  130.                         if (!win_GetDebounced(sed) ||
  131.                             fld != sed_GetFieldNo(sed)) {
  132.  
  133.                             win_SetDebounced(sed, TRUE);
  134.                             mev_ClearEvent(mev);    /* Don't accept it */
  135.                             return(MOU_THERE);        /* code to dropdown func to exit */
  136.                         }
  137.                     }
  138.                     else {    /* No button */
  139.                         parent = disp_GetCurrentWin();
  140.                         if (parent !=NULL && !sed_IsActive(parent)) {
  141.                             sed_SetActive(parent, TRUE);
  142.                             sed_GotoFirstField(parent);
  143.                         }
  144.                     }
  145.                 }
  146.                 win_SetDebounced(sed, mev_IsButtonDown(mev));
  147.                 mev_ClearEvent(mev);    /* Don't accept it */
  148.             }
  149.             case MEV_ENDOFFER:
  150.                 break;
  151.  
  152.             case MEV_REQUEST:
  153.                 /* We never get requests because child never accepts offer */
  154.                 break;
  155.  
  156.             case MEV_STARTEVENT:
  157.             case MEV_EVENT:
  158.             {
  159.                 boolean wasactive;
  160.                 int ret;
  161.  
  162.                 /* Override the _Drag handler by just quitting in this case */
  163.                 if (!mev_IsButtonDown(mev) && !sed_IsActive(sed)) {
  164.                     win_SetDebounced(sed, FALSE);
  165.                     return(MOU_THERE);
  166.                 }
  167.  
  168.                 wasactive = sed_IsActive(sed);
  169.  
  170.                 ret = sedmou_Drag(sed, msg, mev);
  171.                 /* Note: no need to un-trap because we were already trapping */
  172.  
  173.                 if (ret == MOU_HERE) {
  174.                     kb_Stuff(MOU_IGNORE);    /* Un-stuff any click code */
  175.                     if (mev_IsButtonDown(mev)) {
  176.                         /* Button was pressed on a field or dragged to a new field */
  177.                         return(MOU_CLICK);
  178.                     }
  179.                     else {
  180.                         /* Button was released on a field */
  181.                         return(MOU_RELEASE);
  182.                     }
  183.                 }
  184.                 else {
  185.                     if (wasactive && !sed_IsActive(sed)) {
  186.                         /* Left an active field */
  187.                         return(MOU_NOFIELD);
  188.                     }
  189.                 }
  190.             }
  191.             case MEV_ENDEVENT:
  192.                 break;
  193.             }
  194.         }
  195.         else {    /* Event came outside of framer bar (it's greedy) */
  196.             switch(msg) {
  197.  
  198.             case MEV_STARTOFFER:           /* we're not the current window */
  199.             {
  200.                 mev_struct mevs;
  201.  
  202.                 win_SetDebounced(sed, mev_IsButtonDown(mev));
  203.  
  204.                 /* If event is from a bob of the dropdown, suck up mouse events
  205.                     until button rises so that exiting greedy popups will not
  206.                     make us do anything
  207.                 */
  208.                 if (mev_IsButtonDown(mev) && mev_IsFake()) {
  209.                     for (;;) {
  210.                         if (win_ReadEvent(sed, &mevs) == MOU_EVENT) {
  211.                             /* If button released in same field */
  212.                             if (!mev_IsButtonDown(&mevs)) {
  213.                                 win_SetDebounced(sed, FALSE);
  214.                                 break;
  215.                             }
  216.                         }
  217.                     }
  218.                     mev_ClearEvent(mev);    /* Don't accept it */
  219.                     break;
  220.                 }
  221.                 /* no break; fall through */
  222.             }
  223.             case MEV_OFFER:
  224.             {
  225.                 win_type child;
  226.  
  227.                 /* Outside window: dropdown must be current because we must be
  228.                     greedy to get such an event & that means only children can
  229.                     be current */
  230.  
  231.                 /* If button is pressed or released, return a quit msg */
  232.                 if (win_GetDebounced(sed) ^ mev_IsButtonDown(mev)) {
  233.                     mev_ClearEvent(mev);    /* Don't accept it */
  234.                     return(MOU_THERE);    /* code to dropdown func to exit */
  235.                 }
  236.                 /* Turn off any highlighted field while we're dragging */
  237.                 child = disp_GetCurrentWin();
  238.                 if (mev_IsButtonDown(mev) && child != NULL && sed_IsActive(child)) {
  239.                     sed_SetActive(child, FALSE);
  240.                     sed_GotoField(child, sed_GetFieldNo(child));
  241.                 }
  242.                 mev_ClearEvent(mev);    /* Don't accept it */
  243.                 break;
  244.             }
  245.             case MEV_STARTEVENT:
  246.                 win_SetDebounced(sed, mev_IsButtonDown(mev));
  247.             case MEV_EVENT:
  248.             {
  249.                 bob_type bob;
  250.  
  251.                 if (!kb_WasMouse() || mev_IsFake()) {
  252.                     break;
  253.                 }
  254.                 /* Quit the framer if dropdown was aborted by an outside mev */
  255.                 if (msys_IsFrameRtn(sed)) {
  256.                     return(MOU_THERE);
  257.                 }
  258.                 else {
  259.                     if (msg == MEV_STARTEVENT ||
  260.                         (mev_IsButtonDown(mev) != win_GetDebounced(sed))) {
  261.                         win_SetDebounced(sed, mev_IsButtonDown(mev));
  262.  
  263.                         /* If current field has no bob, quit the framer */
  264.                         bob = sed_GetFieldBob(sed, sed_GetFieldNo(sed));
  265.                         if (bob == NULL || bob_IsUfunc(bob) || !win_IsEmployed(bob)) {
  266.                             return(MOU_THERE);
  267.                         }
  268.                         else {    /* field has a bob */
  269.                             /* Mouse has left the framer bar but is not in the
  270.                                 dropdown. This case should act just like when the
  271.                                 mouse is in the bob's framer field */
  272.                             if (!mev_IsButtonDown(mev)) {
  273.                                 return(MOU_RELEASE);
  274.                             }
  275.                         }
  276.                     }
  277.                 }
  278.                 break;
  279.             case MEV_ENDEVENT:
  280.                 break;
  281.             }
  282.             }
  283.         }
  284.     }
  285.     /* Use the following special behavior for framer dropdown menus */
  286.     else switch (msg) {
  287.  
  288.     case MEV_STARTOFFER:    /* A child or parent of the dropdown must be */
  289.     case MEV_OFFER:            /* current; otherwise the dropdown is never up. */
  290.         /* If parent framer is current, send it a code to enter us */
  291.         if (win_GetParent(sed) == disp_GetCurrentWin()) {
  292.             mev_ClearEvent(mev);    /* Don't accept it */
  293.             return(ENTER);
  294.         }
  295.         /* no break; */
  296.  
  297.     case MEV_ENDOFFER:        /* present without being current */
  298.         mev_ClearEvent(mev);    /* Don't accept it */
  299.         break;
  300.  
  301.     case MEV_REQUEST:    /*    We're current; someone else wants to be current */
  302.         /* Request must be from parent framer bar, because it's greedy and its
  303.             children don't accept offers */
  304.  
  305.         /* Don't grant request because we're in a nested 'go', but
  306.             return MOU_THERE as a scancode to kb_Read to tell the dropdown func
  307.             about the request so it can exit */
  308.         return(MOU_THERE);
  309.  
  310.     case MEV_STARTEVENT:
  311.     {
  312.         mev_struct mevs;
  313.  
  314.         if (mev_IsButtonDown(mev)) {
  315.             if (msys_IsFrameRtn(sed) && mev_IsFake()) {
  316.                 /* If event is from a bob of the dropdown, suck up mouse events
  317.                     until button rises so that exiting greedy popups will not
  318.                     make us do anything
  319.                 */
  320.                 for (;;) {
  321.                     if (win_ReadEvent(sed, &mevs) == MOU_EVENT) {
  322.                         /* If button released in same field */
  323.                         if (!mev_IsButtonDown(&mevs)) {
  324.                             win_SetDebounced(sed, FALSE);
  325.                             break;
  326.                         }
  327.                     }
  328.                 }
  329.                 break;
  330.             }
  331.             else {    /* not coming from a bob */
  332.                 win_SetDebounced(sed, TRUE);
  333.  
  334.                 /* Unhighlight lit field and go on to sedmou_Drag */
  335.                 sed_SetActive(sed, FALSE);
  336.                 sed_GotoField(sed, sed_GetFieldNo(sed));
  337.             }
  338.         }
  339.         else {    /* Button not down */
  340.             win_SetDebounced(sed, FALSE);
  341.         }
  342.  
  343.         /* no break, fall through */
  344.     }
  345.     case MEV_EVENT:
  346.     {
  347.         win_type oldtrap;
  348.         int ret;
  349.  
  350.         oldtrap = disp_GetMouseTrap();
  351.         ret = sedmou_Drag(sed, msg, mev);
  352.         disp_TrapMouse(oldtrap);    /* Undo any trapping Drag did */
  353.         return(ret);
  354.     }
  355.     case MEV_ENDEVENT:
  356.         break;
  357.     }
  358.     return(MOU_IGNORE);        /* Ignore this mouse event */
  359. }
  360. /* -------------------------------------------------------------------------- */
  361.  
  362.