home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / BDMOUSE2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-12  |  9.9 KB  |  377 lines

  1. /*
  2.     bdmouse2.c    4/09/90
  3.  
  4.     % mouseable border with vertical and horizontal scroll bars and lights
  5.     % supports a prompt and title
  6.  
  7.     OWL 1.2
  8.     Copyright (c) 1990 by Oakland Group, Inc.
  9.     ALL RIGHTS RESERVED.
  10.  
  11.     Revision History:
  12.     -----------------
  13.      4/09/90 pmcm    wrapped a horizontal variant of bd_sidebar around bd_mouse    
  14.      4/15/90 pmcm    added inpos check to mouse handler to prevent scrolling overshoot
  15.      4/17/90 ted    added textfree dependent coord rounding for pmwin borders
  16.     10/11/90 pmcm    changed scroll bar chars for VMS
  17. */
  18.  
  19. #include "oakhead.h"
  20. #include "disppriv.h"
  21. #include "strdecl.h"
  22. #include "scancode.h"    /* for mouse pseudo-scancodes */
  23.  
  24. #include "bordobj.h"
  25. #include "bordod.h"
  26. #include "bdmou2od.h"
  27.  
  28. #define    HSCROLL_BAR    "\262\262\262"
  29.  
  30. #ifdef OAK_VMS
  31. #    define H_BAR        "\303\304\264"
  32. #else
  33. #    define H_BAR        "\260\260\260"
  34. #endif
  35.  
  36. #ifdef BORDER_CHARS
  37. #    define    leftlight(bdmou2dd)        ((bdmou2dd->left)      ? "\x11" : &bdmou2dd->back)
  38. #    define    rightlight(bdmou2dd)    ((bdmou2dd->right)     ? "\x10" : &bdmou2dd->back)
  39. #    define  LEFTCORNER                "\xC3\xC0\xC0"
  40. #    define     RIGHTCORNER                "\xB4\xD9\xD9"
  41. #else
  42. #    define    leftlight(bdmou2dd)        ((bdmou2dd->left)     ? "*" : &bdmou2dd->back)
  43. #    define    rightlight(bdmou2dd)    ((bdmou2dd->right)     ? "*" : &bdmou2dd->back)
  44. #    define  LEFTCORNER                "+++"
  45. #    define     RIGHTCORNER                "+++"
  46. #endif
  47.  
  48. OSTATIC void OWLPRIV hbar_mouse(bdmouse2_od *, mev_struct *);
  49. OSTATIC void OWLPRIV light_scroll(bdmouse2_od *, opoint *, boolean *, mev_struct *);
  50. /* -------------------------------------------------------------------------- */
  51.  
  52. int bd_mouse2(VOID *objdata, int msg, VOID *indata,    VOID *outdata)
  53.  
  54. /*
  55.     This is a simple single lined border.
  56.     With an title and prompt line.
  57.     The title is pointed to by the border data pointer.
  58.     Example:
  59.                      +-----Title-----+
  60.                      |                 <--- Scroll Lights
  61.                      |               I
  62.                      |               X    <--- Elevator for Vertical scroll bar
  63.                      |               I
  64.                      |                 <--- Scroll Lights
  65.                      +Prompt---------+
  66.                      +  ----X------  +    <--- Horizontal scroll bar & lights
  67.  
  68.     Clicking the mouse on the scroll lights scrolls the border's contents.
  69.     Dragging the mouse on an edge moves the window.
  70.     Dragging the mouse on a corner resizes the window.
  71.  
  72. */
  73. {
  74.     bdmouse2_od     *bdmou2od;
  75.     ocbox            cbox;
  76.     ptd_struct         *ptd;
  77.     win_type        win;
  78.     mev_struct         *mev;
  79.     byte            attr;
  80.  
  81.     bdmou2od = (bdmouse2_od *)objdata;
  82.  
  83.     if(!(msg == OBJM_GETDATASIZE || msg == OBJM_OPEN)) {
  84.         win = bdmou2od->mou1.prompt.bdd.win;
  85.     }
  86.  
  87.     switch(msg) {
  88.     case OBJM_GETDATASIZE:
  89.         ((ogds_struct *) outdata)->odsize = sizeof(bdmouse2_od);
  90.         ((ogds_struct *) outdata)->xdsize = sizeof(border_xd);
  91.         ((ogds_struct *) outdata)->id = ID_BDMOUSE2;
  92.         break;
  93.  
  94.     case OBJM_OPEN:
  95.         if (!bd_mouse(&bdmou2od->mou1, msg, indata, outdata)) {
  96.             return(FALSE);
  97.         }                  
  98.  
  99.         bdmou2od->back     = '\304';
  100.  
  101.         /* This bord must be charsize */
  102.         win_SetCharSize(bdmou2od->mou1.prompt.bdd.win, TRUE);
  103.         bord_SetSides(bdmou2od->mou1.prompt.bdd.win, -1, -1, 2, 1);
  104.                               
  105.         bdmou2od->elleft       = 1;
  106.         bdmou2od->elright   = win_GetWidth(bdmou2od->mou1.prompt.bdd.win) - 2;
  107.  
  108.         bord_GetHzBar(bdmou2od->mou1.prompt.bdd.win, 
  109.             &bdmou2od->elleft, &bdmou2od->elright,    &bdmou2od->left, &bdmou2od->right);
  110.  
  111.         break;
  112.  
  113.     case BDM_SCROLL:
  114.         /* Adjust the left and right lights and the scroll bar */
  115.  
  116.         cbox.toprow   = win_GetHeight(win) + 1;
  117.         cbox.botrow   = cbox.toprow;
  118.         cbox.leftcol  = 0;
  119.         cbox.rightcol = win_GetWidth(win) - 1;
  120.  
  121.         bdmou2od->elleft       = cbox.leftcol  + 1;
  122.         bdmou2od->elright   = cbox.rightcol - 1;
  123.         bord_GetHzBar(win, &bdmou2od->elleft, &bdmou2od->elright,
  124.                            &bdmou2od->left,   &bdmou2od->right);
  125.  
  126.         win_PaintBox(win, &cbox);
  127.  
  128.         /* pass it up */
  129.         bd_mouse(&bdmou2od->mou1, msg, indata, outdata);
  130.  
  131.         break;
  132.  
  133.     case BDM_RESIZE:                      
  134.         /* our window has changed size, reset the scroll lights */
  135.         bdmou2od->elleft       = 1;
  136.         bdmou2od->elright   = win_GetWidth(win) - 2;
  137.         bord_GetHzBar(win, &bdmou2od->elleft,     &bdmou2od->elright,
  138.                            &bdmou2od->left,     &bdmou2od->right);
  139.         bd_mouse(&bdmou2od->mou1, msg, indata, outdata);
  140.         break;
  141.  
  142.     case BDM_SHADOW:
  143.     case BDM_DRAW:
  144.         ptd = (ptd_struct *)indata;
  145.         attr = (msg == BDM_DRAW) ?     bord_GetAttr(win) : win_GetShadowAttr(win);
  146.  
  147.         /* Draw the scroll bar */
  148.  
  149.         cbox.toprow   = win_GetHeight(win) + 1;
  150.         cbox.botrow   = cbox.toprow;
  151.         cbox.leftcol  = 1;
  152.         cbox.rightcol = win_GetWidth(win) - 2;
  153.  
  154.         if (cbox.rightcol >= cbox.leftcol) {
  155.             ptd_DrawCharLine(ptd, H_BAR, &cbox, attr);
  156.  
  157.             cbox.leftcol       = bdmou2od->elleft;
  158.             cbox.rightcol   = bdmou2od->elright;
  159.             ptd_DrawCharLine(ptd, HSCROLL_BAR, &cbox, attr);
  160.         }
  161.  
  162.         /* Draw the scroll lights */
  163.  
  164.         cbox.leftcol     = 0;
  165.         cbox.rightcol     = win_GetWidth(win) - 1;
  166.  
  167.         if (cbox.leftcol < cbox.rightcol) {
  168.             /* Leftlight */
  169.             ptd_DrawString(ptd, cbox.toprow, cbox.leftcol,
  170.                             leftlight(bdmou2od), attr, 1);            /* Rightlight */
  171.             ptd_DrawString(ptd, cbox.toprow, cbox.rightcol,
  172.                             rightlight(bdmou2od), attr, 1);
  173.         }
  174.         else {
  175.             /* fill in char under absent scroll light(s) */
  176.             ptd_DrawString(ptd, cbox.toprow, cbox.leftcol,
  177.                             &bdmou2od->back, attr, 1);
  178.         }
  179.  
  180.         bd_mouse(&bdmou2od->mou1, msg, indata, outdata);
  181.  
  182.         /* Draw the bottom corners after we pass it up */
  183.  
  184.         cbox.leftcol     = -1;
  185.         cbox.rightcol     = -1;
  186.         cbox.toprow        = win_GetHeight(win);
  187.         ptd_DrawCharLine(ptd, LEFTCORNER,   &cbox, attr);
  188.         cbox.leftcol    = win_GetWidth(win); 
  189.         cbox.rightcol    = cbox.leftcol;
  190.         ptd_DrawCharLine(ptd, RIGHTCORNER,  &cbox, attr);
  191.         
  192.         break;
  193.  
  194.     case BDM_STARTMOUSE:
  195.     case BDM_ENDMOUSE:
  196.         return(bd_mouse(&bdmou2od->mou1, msg, indata, outdata));
  197.  
  198.     case BDM_MOUSE:
  199.         /* If mouse clicked on left or right light, then scroll. */
  200.         /* If mouse clicked on elevator, scroll in that fashion */
  201.  
  202.         mev = (mev_struct *) indata;
  203.  
  204.         if (mev_GetRow(mev) == win_GetHeight(win) + 1 &&
  205.             mev_GetCol(mev) >= 0 &&
  206.             mev_GetCol(mev) <= win_GetWidth(win) - 1) {
  207.  
  208.             hbar_mouse(bdmou2od, mev);
  209.  
  210.             /* Don't offer to make this border's window the current window */
  211.             mev_ClearEvent(mev);
  212.         }
  213.         else {
  214.             /* pass message up to super class */
  215.             return(bd_mouse(&bdmou2od->mou1, msg, indata, outdata));
  216.         }
  217.  
  218.         break;
  219.  
  220.     case OBJM_CLOSE:
  221.         /* No break; fall through to default */
  222.  
  223.     default:
  224.         bd_mouse(&bdmou2od->mou1, msg, indata, outdata);
  225.         break;
  226.     }
  227.     return(1);
  228. }
  229. /* -------------------------------------------------------------------------- */
  230.  
  231. static void OWLPRIV hbar_mouse(bdmouse2_od *bdmou2od, mev_struct *mev)
  232.  
  233. /*
  234.     Mouse processing for horizontal scroll bar of bd_mouse2.
  235. */
  236.  
  237. {
  238.     win_type    win;
  239.     opoint         mvpnt;
  240.     boolean    *actdirp;
  241.     opcoord        prevx, tempx;
  242.     int            elevw, barw;
  243.     inposdata_struct inpos;
  244.  
  245.     if (mev_IsButtonDown(mev)) {
  246.         if (bdmou2od->mou1.prompt.bdd.debounced) {
  247.             return;
  248.         }
  249.     }
  250.     else {
  251.         bdmou2od->mou1.prompt.bdd.debounced = FALSE;
  252.         return;
  253.     }
  254.     win = bdmou2od->mou1.prompt.bdd.win;
  255.  
  256.     if (mev_GetCol(mev) == 0) {
  257.         /* Left arrow */
  258.         if (bdmou2od->left) {
  259.             actdirp = &bdmou2od->left;
  260.             mvpnt.y = 0;
  261.             mvpnt.x = -win_GetFontWidth(win);
  262.  
  263.             light_scroll(bdmou2od, &mvpnt, actdirp, mev);
  264.         }
  265.     }
  266.     else if (mev_GetCol(mev) == win_GetWidth(win) - 1) {
  267.         /* Right arrow */
  268.         if (bdmou2od->right) {
  269.             actdirp = &bdmou2od->right;
  270.             mvpnt.y = 0;
  271.             mvpnt.x = win_GetFontWidth(win);
  272.  
  273.             light_scroll(bdmou2od, &mvpnt, actdirp, mev);
  274.         }
  275.     }
  276.     else if (mev_GetCol(mev) > 0 &&
  277.              mev_GetCol(mev) < win_GetWidth(win) - 1 ) {
  278.  
  279.         /* Hbar */
  280.         if ((barw = (win_GetWidth(win) - 2)) >= 2) {
  281.  
  282.             inpos.win = win;
  283.  
  284.             prevx = mev_GetX(mev);
  285.             mvpnt.y = 0;
  286.             
  287.             /* scaling factor is ratio of scroll bar width to elevator width */
  288.             elevw = bdmou2od->elright - bdmou2od->elleft + 1;
  289.  
  290.             for (;;) {
  291.                 win_Do(win, WINM_GETINPOS, NULL, &inpos);
  292.  
  293.                 mvpnt.x = (mev_GetX(mev) - prevx) * barw / elevw;
  294.  
  295.                 if (mvpnt.x < 0) {
  296.                     /* Don't scroll left too much */
  297.                     tempx = inpos.inbox.xmin;
  298.                     if (mvpnt.x < tempx) {
  299.                         mvpnt.x = tempx;
  300.                     }
  301.                     if (mvpnt.x > 0) {
  302.                         mvpnt.x = 0;
  303.                     }
  304.                     else {
  305.                         /* Round down to character boundary */
  306.                         if (!disp_TextFree()) {
  307.                             opcoord_GridRound(&mvpnt.x, &mvpnt.y, win_GetFont(win));
  308.                         }
  309.                     }
  310.                 }
  311.                 else {
  312.                     /* Don't scroll right too much */
  313.                     tempx = inpos.inbox.xmax - win_GetPixWidth(win);
  314.                     if (mvpnt.x > tempx) {
  315.                         mvpnt.x = tempx;
  316.                     }
  317.                     if (mvpnt.x < 0) {
  318.                         mvpnt.x = 0;
  319.                     }
  320.                     else {
  321.                         /* Round up to character boundary */
  322.                         if (!disp_TextFree()) {
  323.                             mvpnt.x += win_GetFontWidth(win) - 1;
  324.                             opcoord_GridRound(&mvpnt.x, &mvpnt.y, win_GetFont(win));
  325.                         }
  326.                     }
  327.                 }
  328.  
  329.                 if (mvpnt.x != 0) {
  330.                     /* Scroll window contents */
  331.                     win_Do(win, WINM_SCROLLREQ, &mvpnt, NULL);
  332.                 }
  333.  
  334.                 if (win_ReadEvent(win, mev) == MOU_EVENT) {
  335.                     if (!mev_IsButtonDown(mev)) {
  336.                         break;
  337.                     }
  338.                 /* else: ignore keystrokes */
  339.                 }
  340.             }
  341.         }
  342.     }
  343.     bdmou2od->mou1.prompt.bdd.debounced = mev_IsButtonDown(mev);
  344. }
  345. /* -------------------------------------------------------------------------- */
  346.  
  347. static void OWLPRIV light_scroll(bdmouse2_od *bdmou2od, opoint *mvpnt, boolean *actdirp, mev_struct *mev)
  348. {
  349.     win_type    win;
  350.     unsigned    holdtime;
  351.  
  352.     win = bdmou2od->mou1.prompt.bdd.win;
  353.  
  354.     holdtime = 30;    /* Initial delay value = 1/3 second */
  355.  
  356.     for (;;) {
  357.         /* Scroll window contents */
  358.         /* Note that the SCROLLREQ is expected to call BDM_SCROLL */
  359.         /* to reset the lights flags which we test to see if */
  360.         /* scrolling is all done */
  361.         win_Do(win, WINM_SCROLLREQ, mvpnt, NULL);
  362.  
  363.         /* Break if dir is all used up now */
  364.         if (!(*actdirp)) {
  365.             bdmou2od->mou1.prompt.bdd.debounced = TRUE;
  366.             break;
  367.         }
  368.         /* Break if mouse is no longer held down. Ignore keyhits */
  369.         if (win_MouseHoldDownTime(win, mev, holdtime) != MOU_HOLDDOWN) {
  370.             break;
  371.         }
  372.         holdtime = 5;
  373.     }
  374. }
  375. /* -------------------------------------------------------------------------- */
  376.  
  377.