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

  1. /*
  2.     bdside.c    12/18/88
  3.  
  4.     % an elevator side bar with scroll lights and scrolling mouse support.
  5.  
  6.     OWL 1.2
  7.     Copyright (c) 1988, 1989 by Oakland Group, Inc.
  8.     ALL RIGHTS RESERVED.
  9.  
  10.     Revision History:
  11.     -----------------
  12.      5/28/89 jmd    added Shadow (non) support
  13.     11/01/89 jdc    fixed win_MouseHoldDownTime loop
  14.     11/06/89 jmd    removed DoRaw macros
  15.  
  16.      2/21/90 ted    Added SetCharSize(TRUE) because border won't work otherwise.
  17.      3/28/90 jmd    ansi-fied
  18.      4/15/90 pmcm    added inpos check to mouse handler to prevent scrolling overshoot
  19.      4/17/90 ted    added textfree dependent coord rounding for pmwin borders
  20.     10/11/90 pmcm    changed scroll bar chars for VMS
  21. */
  22.  
  23. #include "oakhead.h"
  24. #include "disppriv.h"
  25. #include "scancode.h"    /* for mouse pseudo-scancodes */
  26. #include "strdecl.h"
  27.  
  28. #include "bordobj.h"
  29. #include "bordod.h"
  30. #include "bdsideod.h"
  31.  
  32. #define    VSCROLL_BAR    "\262\262\262"
  33.  
  34. #ifdef OAK_VMS
  35. #    define VSIDE_BAR    "\302\263\301"
  36. #else
  37. #    define VSIDE_BAR    "\260\260\260"
  38. #endif
  39.  
  40. #ifdef BORDER_CHARS
  41. #    define    uplight(bdsided)    ((bdsided->up) ? "\x1e" : &bdsided->back)
  42. #    define    downlight(bdsided)    ((bdsided->down) ? "\x1f" : &bdsided->back)
  43. #else
  44. #    define    uplight(bdsided)    ((bdsided->up) ? "*" : &bdsided->back)
  45. #    define    downlight(bdsided)    ((bdsided->down) ? "*" : &bdsided->back)
  46. #endif
  47.  
  48. OSTATIC void OWLPRIV sidebar_mouse(bdsidebar_od *bdsideod, mev_struct *mev);
  49. OSTATIC void OWLPRIV light_scroll(bdsidebar_od *bdsideod, opoint *mvpnt, boolean *actdirp, mev_struct *mev);
  50. /* -------------------------------------------------------------------------- */
  51.  
  52. int bd_sidebar(VOID *objdata, int msg, VOID *indata, VOID *outdata)
  53. /*
  54.     Example:
  55.                                        <--- Scroll Lights
  56.                                      I
  57.                                      X    <--- Elevator
  58.                                      I
  59.                                        <--- Scroll Lights
  60.     Clicking the mouse on the scroll lights or the sidebar
  61.         scrolls the border's contents.
  62. */
  63. {
  64.     bdsidebar_od *bdsideod;
  65.     ocbox        cbox;
  66.     ptd_struct *ptd;
  67.     win_type    win;
  68.     mev_struct *mev;
  69.     byte        attr;
  70.  
  71.     bdsideod = (bdsidebar_od *)objdata;
  72.  
  73.     switch(msg) {
  74.     case OBJM_GETDATASIZE:
  75.         ((ogds_struct *) outdata)->odsize = sizeof(bdsidebar_od);
  76.         ((ogds_struct *) outdata)->xdsize = sizeof(border_xd);
  77.         ((ogds_struct *) outdata)->id = ID_BDSIDEBAR;
  78.         break;
  79.  
  80.     case OBJM_OPEN:
  81.         if (!border_Class(&bdsideod->bdd, msg, indata, outdata)) {
  82.             return(FALSE);
  83.         }
  84.          bdsideod->back = ' ';
  85.  
  86.         win_SetCharSize(bdsideod->bdd.win, TRUE);    /* This bord must be charsize */
  87.         bord_SetSides(bdsideod->bdd.win, 0, 0, 0, 1);
  88.  
  89.         bdsideod->eltop   = 1;
  90.         bdsideod->elbot   = win_GetHeight(bdsideod->bdd.win) - 2;
  91.         bord_GetVtBar(bdsideod->bdd.win, &bdsideod->eltop, &bdsideod->elbot,
  92.                                             &bdsideod->up, &bdsideod->down);
  93.         break;
  94.  
  95.     case BDM_SCROLL:
  96.         /* Adjust the up and down lights and the scroll bar */
  97.         win = bdsideod->bdd.win;
  98.  
  99.         cbox.toprow   = 0;
  100.         cbox.botrow   = win_GetHeight(win) - 1;
  101.         cbox.leftcol  = win_GetWidth(win);
  102.         cbox.rightcol = cbox.leftcol;
  103.  
  104.         bdsideod->eltop   = cbox.toprow + 1;
  105.         bdsideod->elbot   = cbox.botrow - 1;
  106.         bord_GetVtBar(win, &bdsideod->eltop, &bdsideod->elbot,
  107.                             &bdsideod->up, &bdsideod->down);
  108.  
  109.         win_PaintBox(win, &cbox);
  110.         break;
  111.  
  112.     case BDM_RESIZE:
  113.         /* our window has changed size, reset the scroll lights */
  114.         bdsideod->eltop   = 1;
  115.         bdsideod->elbot   = win_GetHeight(bdsideod->bdd.win) - 2;
  116.         bord_GetVtBar(bdsideod->bdd.win, &bdsideod->eltop, &bdsideod->elbot,
  117.                                             &bdsideod->up, &bdsideod->down);
  118.         break;
  119.  
  120.     case BDM_SHADOW:
  121.     case BDM_DRAW:
  122.         ptd = (ptd_struct *)indata;
  123.         win = bdsideod->bdd.win;
  124.         attr = (msg == BDM_DRAW) ? 
  125.             bord_GetAttr(bdsideod->bdd.win) : win_GetShadowAttr(bdsideod->bdd.win);
  126.  
  127.         /* Draw the scroll bar */
  128.  
  129.         cbox.leftcol  = win_GetWidth(win);
  130.         cbox.rightcol = cbox.leftcol;
  131.         cbox.toprow   = 1;
  132.         cbox.botrow   = win_GetHeight(win) - 2;
  133.         if (cbox.botrow >= cbox.toprow) {
  134.             ptd_DrawCharLine(ptd, VSIDE_BAR, &cbox, attr);
  135.  
  136.             cbox.toprow   = bdsideod->eltop;
  137.             cbox.botrow   = bdsideod->elbot;
  138.             ptd_DrawCharLine(ptd, VSCROLL_BAR, &cbox, attr);
  139.         }
  140.         /* Draw the scroll lights */
  141.         cbox.toprow = 0;
  142.         cbox.botrow = win_GetHeight(win) - 1;
  143.         if (cbox.botrow > cbox.toprow) {
  144.             /* Uplight */
  145.             ptd_DrawString(ptd, cbox.toprow, cbox.rightcol,
  146.                             uplight(bdsideod), attr, 1);
  147.             /* Downlight */
  148.             ptd_DrawString(ptd, cbox.botrow, cbox.rightcol,
  149.                             downlight(bdsideod), attr, 1);
  150.         }
  151.         /* Note: this border does not support a shadow
  152.                  so it doesn't pass up its DRAW msg 
  153.         */
  154.         break;
  155.  
  156.     case BDM_STARTMOUSE:
  157.     case BDM_ENDMOUSE:        /* Mouse left the border. */
  158.         return(border_Class(&bdsideod->bdd, msg, indata, outdata));
  159.  
  160.     case BDM_MOUSE:
  161.         /* If mouse clicked on up or down light, then scroll. */
  162.         /* If mouse clicked on elevator, scroll in that fashion */
  163.  
  164.         mev = (mev_struct *) indata;
  165.         win = bdsideod->bdd.win;
  166.  
  167.         if (mev_GetCol(mev) == win_GetWidth(win) &&
  168.             mev_GetRow(mev) >= 0 &&
  169.             mev_GetRow(mev) <= win_GetHeight(win) - 1) {
  170.  
  171.             sidebar_mouse(bdsideod, mev);
  172.  
  173.             /* Don't offer to make this border's window the current window */
  174.             mev_ClearEvent(mev);
  175.         }
  176.         else {
  177.             /* pass message up to super class */
  178.             return(border_Class(&bdsideod->bdd, msg, indata, outdata));
  179.         }
  180.         break;
  181.  
  182.     case OBJM_CLOSE:
  183.         /* No break; fall through to default */
  184.  
  185.     default:
  186.         return(border_Class(&bdsideod->bdd, msg, indata, outdata));
  187.     }
  188.     return(1);
  189. }
  190. /* -------------------------------------------------------------------------- */
  191.  
  192. static void OWLPRIV sidebar_mouse(bdsidebar_od *bdsideod, mev_struct *mev)
  193. /*
  194.     Mouse processing for bd_sidebar.
  195. */
  196. {
  197.     win_type    win;
  198.     opoint         mvpnt;
  199.     boolean    *actdirp;
  200.     opcoord        prevy, tempy;
  201.     int            elevh, barh;
  202.     inposdata_struct inpos;
  203.  
  204.     if (mev_IsButtonDown(mev)) {
  205.         if (bdsideod->bdd.debounced) {
  206.             return;
  207.         }
  208.     }
  209.     else {
  210.         bdsideod->bdd.debounced = FALSE;
  211.         return;
  212.     }
  213.     win = bdsideod->bdd.win;
  214.  
  215.     if (mev_GetRow(mev) == 0) {
  216.         /* Up arrow */
  217.         if (bdsideod->up) {
  218.             actdirp = &bdsideod->up;
  219.             mvpnt.x = 0;
  220.             mvpnt.y = -win_GetFontHeight(win);
  221.  
  222.             light_scroll(bdsideod, &mvpnt, actdirp, mev);
  223.         }
  224.     }
  225.     else if (mev_GetRow(mev) == win_GetHeight(win) - 1) {
  226.         /* Down arrow */
  227.         if (bdsideod->down) {
  228.             actdirp = &bdsideod->down;
  229.             mvpnt.x = 0;
  230.             mvpnt.y = win_GetFontHeight(win);
  231.  
  232.             light_scroll(bdsideod, &mvpnt, actdirp, mev);
  233.         }
  234.     }
  235.     else if (mev_GetRow(mev) > 0 &&
  236.              mev_GetRow(mev) < win_GetHeight(win) - 1 ) {
  237.  
  238.         /* Sidebar */
  239.         if ((barh = (win_GetHeight(win) - 2)) >= 2) {
  240.  
  241.             inpos.win = win;
  242.  
  243.             prevy = mev_GetY(mev);
  244.             mvpnt.x = 0;
  245.             
  246.             /* scaling factor is ratio of scroll bar height to elevator height */
  247.             elevh = bdsideod->elbot - bdsideod->eltop + 1;
  248.  
  249.             for (;;) {
  250.                 win_Do(win, WINM_GETINPOS, NULL, &inpos);
  251.  
  252.                 mvpnt.y = (mev_GetY(mev) - prevy) * barh / elevh;
  253.  
  254.                 if (mvpnt.y < 0) {
  255.                     /* Don't scroll up too much */
  256.                     tempy = inpos.inbox.ymin;
  257.                     if (mvpnt.y < tempy) {
  258.                         mvpnt.y = tempy;
  259.                     }
  260.                     if (mvpnt.y > 0) {
  261.                         mvpnt.y = 0;
  262.                     }
  263.                     else {
  264.                         /* Round down to character boundary */
  265.                         if (!disp_TextFree()) {
  266.                             opcoord_GridRound(&mvpnt.x, &mvpnt.y, win_GetFont(win));
  267.                         }
  268.                     }
  269.                 }
  270.                 else {
  271.                     /* Don't scroll down too much */
  272.                     tempy = inpos.inbox.ymax - win_GetPixHeight(win);
  273.                     if (mvpnt.y > tempy) {
  274.                         mvpnt.y = tempy;
  275.                     }
  276.                     if (mvpnt.y < 0) {
  277.                         mvpnt.y = 0;
  278.                     }
  279.                     else {
  280.                         /* Round up to character boundary */
  281.                         if (!disp_TextFree()) {
  282.                             mvpnt.y += win_GetFontHeight(win) - 1;    /* Round up */
  283.                             opcoord_GridRound(&mvpnt.x, &mvpnt.y, win_GetFont(win));
  284.                         }
  285.                     }
  286.                 }
  287.  
  288.                 if (mvpnt.y != 0) {
  289.                     /* Scroll window contents */
  290.                     win_Do(win, WINM_SCROLLREQ, &mvpnt, NULL);
  291.                 }
  292.  
  293.                 if (win_ReadEvent(win, mev) == MOU_EVENT) {
  294.                     if (!mev_IsButtonDown(mev)) {
  295.                         break;
  296.                     }
  297.                 /* else: ignore keystrokes */
  298.                 }
  299.             }
  300.         }
  301.     }
  302.     bdsideod->bdd.debounced = mev_IsButtonDown(mev);
  303. }
  304. /* -------------------------------------------------------------------------- */
  305.  
  306. static void OWLPRIV light_scroll(bdsidebar_od *bdsideod, opoint *mvpnt, boolean *actdirp, mev_struct *mev)
  307. {
  308.     win_type    win;
  309.     unsigned    holdtime;
  310.  
  311.     win = bdsideod->bdd.win;
  312.  
  313.     holdtime = 30;    /* Initial delay value = 1/3 second */
  314.  
  315.     for (;;) {
  316.         /* Scroll window contents */
  317.         /* Note that the SCROLLREQ is expected to call BDM_SCROLL */
  318.         /* to reset the lights flags which we test to see if */
  319.         /* scrolling is all done */
  320.         win_Do(win, WINM_SCROLLREQ, mvpnt, NULL);
  321.  
  322.         /* Break if dir is all used up now */
  323.         if (!(*actdirp)) {
  324.             bdsideod->bdd.debounced = TRUE;
  325.             break;
  326.         }
  327.         /* Break if mouse is no longer held down. Ignore keyhits */
  328.         if (win_MouseHoldDownTime(win, mev, holdtime) != MOU_HOLDDOWN) {
  329.             break;
  330.         }
  331.         holdtime = 5;
  332.     }
  333. }
  334. /* -------------------------------------------------------------------------- */
  335.  
  336.