home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 328_02 / wscrllbr.c < prev    next >
C/C++ Source or Header  |  1991-03-17  |  7KB  |  288 lines

  1. /* WSCRLLBR.C - contains routines for vertical mouse-driven scrollbars.
  2.  *
  3.  *         wscrollbar_add () - create a scrollbar
  4.  *            PARAMS: key = a non-keyboard keyvalue (negative is best) for ID
  5.  *                              This value will be returned by wgetc()
  6.  *                            when the mouse clicks on the scrollbar image area.
  7.  *                    x    = x-location in window for scrollbar.
  8.  *                    y1, y2= top and bottom locations of scrollbar.
  9.  *                    range = unsigned int value giving virtual position of ptr
  10.  *                            when ptr=y1, virtual position is 0.
  11.  *                            when ptr=y2, virtual value is 'range'
  12.  *                    start = unsigned int = starting virtual value of scrollbar.
  13.  *            RETURNS: WBUTTON *Bptr = ptr to the scrollbar data, used below.
  14.  *
  15.  *        wscrollbar_draw() - draw, or redraw scrollbar
  16.  *            PARAMS:  WBUTTON *Bptr = pts to the scrollbar data.
  17.  *            RETURNS: void.
  18.  *
  19.  *         wscrollbar_scroll() - allow mouse to move scrollbar ptr onscreen.
  20.  *            USE: when wgetc() returns the key that identifies the scrollbar,
  21.  *                the mouse state is: LEFT BUTTON newly pressed, on scrollbar.
  22.  *                Call wscrollbar_scroll() to track the mouse mvt and get new ptr
  23.  *            PARAMS: WBUTTON *Bptr = ptr to scrollbar data area
  24.  *                                    (obtained from wscrollbar_add() )
  25.  *            RETURNS: unsigned int newval = new virtual position 
  26.  *                        0 <= newval <= range
  27.  *                            
  28.  *        wscrollbar_reset() - provide new virtual position for the scrollbar 
  29.  *                             and redraw the ptr onscreen.
  30.  *            PARAMS: WBUTTON *Bptr = ptr to scrollbar data.
  31.  *                    unsigned int newval = new virtual value.
  32.  *
  33.  *    NOTES: no error checking is performed. Be careful of following:
  34.  *            The scrollbar must be AT LEAST 4 bytes long (y2 > y1+3)
  35.  *            The range must be > 2.
  36.  *            The key assigned should not be producable on a PC/AT keyboard
  37.  *                (prog. will lock if a keyboard press activates the scrollbar)
  38.  *                (negative key values are guaranteed to work)
  39.  *            
  40.  *
  41.  */
  42. #include "wsys.h"
  43.  
  44.     /* ASCI values for drawing scrollbar */
  45. #define  IMAGE_UP    '\x1E'
  46. #define  IMAGE_DN    '\x1F'
  47. #define  IMAGE_BAR    '\xB0'
  48. #define  IMAGE_PTR    '\xB2'
  49.  
  50.  
  51. static void W_NEAR draw_bar ( WBUTTON *Bptr );
  52. static void W_NEAR draw_ptr ( WBUTTON *Bptr, char ptr_char );
  53.  
  54. static unsigned char W_NEAR get_y(unsigned char y1, unsigned char y2, 
  55.                                 unsigned int val, unsigned int range );
  56.  
  57.  
  58. WBUTTON *wscrollbar_add ( int key, 
  59.             unsigned char ux, unsigned char uy1, unsigned char uy2,
  60.             unsigned int range, unsigned int start )
  61.     {
  62.     WBUTTON *Bptr;
  63.     
  64.     /* allocate storage and place new button in linked list
  65.      */
  66.     Bptr = wmalloc ( sizeof (WBUTTON), "wbutton_add" );
  67.     Bptr->Bchain = w0->winbutton;
  68.     w0->winbutton = Bptr;
  69.  
  70.     Bptr-> Bval  = key;
  71.     Bptr-> Bstyle= WBTN_SCROLL + WBTN_ACTIVE;
  72.  
  73.     Bptr-> Bx    = ux;
  74.     Bptr-> Bxend = ux+1;
  75.     
  76.     
  77.     Bptr-> By    = uy1;
  78.     Bptr-> Byend = uy2;
  79.     
  80.     Bptr-> Brange       = range;
  81.     Bptr-> Bscrollval = start;
  82.  
  83.     draw_bar ( Bptr );
  84.  
  85.     return (Bptr);    /* wscrollbar_add()  */            
  86.     }
  87.             
  88. void             wscrollbar_draw   ( WBUTTON *Bptr )
  89.     {
  90.     draw_bar ( Bptr );
  91.     return;
  92.     }
  93.     
  94. void             wscrollbar_reset  ( WBUTTON *Bptr, unsigned int newval )
  95.     {
  96.     
  97.     draw_ptr ( Bptr, IMAGE_BAR );
  98.     
  99.     Bptr-> Bscrollval = newval;
  100.     draw_ptr ( Bptr, IMAGE_PTR );
  101.     
  102.     return;        /* wscrollbar_reset () */
  103.     }
  104.  
  105.  
  106. /* convert virtual scroll value to onscreen position of ptr.
  107.  * Note that the scrollbar image is 2 bytes short to allow UP/DN icons.
  108.  */
  109. static unsigned char W_NEAR get_y(unsigned char y1, unsigned char y2, 
  110.                                 unsigned int val, unsigned int range )
  111.     {
  112.     register unsigned char y;
  113.     
  114.     y = y1+1 + ( ( val * (y2-y1-2) ) / range );
  115.     
  116.     return (y);        /* get_y */
  117.     }
  118.     
  119.     
  120.     /* draw the entire scrollbar
  121.      */
  122. static void W_NEAR draw_bar ( WBUTTON *Bptr )
  123.     {
  124.     int n;
  125.     int x, y1, y2;
  126.     
  127.     
  128.     x  = Bptr-> Bx;
  129.     y1 = Bptr-> By;
  130.     y2 = Bptr-> Byend;    
  131.     
  132.     
  133.     wgoto ( x, y1 );
  134.     wputc ( IMAGE_UP ); 
  135.     
  136.     for ( n = y1+1; n<y2; ++n )
  137.         {
  138.         wgoto ( x,n );
  139.         wputc ( IMAGE_BAR );
  140.         }
  141.     
  142.     wgoto ( x, y2 );
  143.     wputc ( IMAGE_DN ); 
  144.     
  145.     draw_ptr ( Bptr, IMAGE_PTR );
  146.     
  147.     return;        /* draw_bar */
  148.     }
  149.  
  150.  
  151.  
  152. static void W_NEAR draw_ptr ( WBUTTON *Bptr, char ptr_char )
  153.     {
  154.     
  155.     wgoto ( Bptr-> Bx, 
  156.             get_y ( Bptr->By, Bptr->Byend, Bptr->Bscrollval,Bptr->Brange ) );
  157.  
  158.     wputc ( ptr_char );
  159.     
  160.     return;        /* draw_ptr */
  161.     }
  162.  
  163.     
  164.     /* wscroll_bar_scroll() -
  165.      *     On entry to this routine, the mouse is assumed to be in a state of:
  166.      *        LEFT BUTTON down.
  167.      */
  168.     
  169. unsigned int     wscrollbar_scroll ( WBUTTON *Bptr )
  170.     {
  171.     unsigned int val, range;
  172.     unsigned char x, xbar, y1, y2, y, oldy;
  173.     int redraw =0;
  174.     unsigned char ylen;
  175.     
  176.         
  177.     xbar     = Bptr->Bx;
  178.     y1       = Bptr->By;        
  179.     y2       = Bptr->Byend;
  180.     val     = Bptr->Bscrollval; 
  181.     range   = Bptr->Brange;
  182.     ylen    = y2-y1 -2;        /* length of actual scrollbar */
  183.     
  184.     oldy    = get_y ( y1, y2, val, range );
  185.     
  186.     /* erase the current ptr 
  187.      */
  188.     wgoto ( xbar, oldy );
  189.     wputc ( IMAGE_BAR );
  190.     
  191.     range     = Bptr->Brange;
  192.     wmouse_turn (ON);
  193.     do
  194.         {
  195.  
  196.  
  197.         x= wmouse.wms_x;
  198.         y= wmouse.wms_y;
  199.         
  200.         if ( (x==xbar)  && (y > y1) && (y < y2) )
  201.             {
  202.             /* Inside actual bar (not counting the up/dn icons) 
  203.              */
  204.             
  205.             if ( oldy != y )
  206.                 {
  207.                 /* avoid garbage on EGA/VGA monitors by turning of mouse
  208.                  * while drawing (if  in graphics mode) 
  209.                  */
  210.                 wmouse_turn (OFF);
  211.                 
  212.                 val =  ( ( y-y1-1 ) * ( range ) ) / (ylen);
  213.  
  214.                 wgoto ( xbar, oldy );
  215.                 wputc ( IMAGE_BAR );
  216.                 
  217.                 oldy = y;
  218.                 
  219.                 wgoto ( xbar, y );
  220.                 wputc ( IMAGE_PTR );
  221.                 
  222.                 wmouse_turn (ON);
  223.                 
  224.                 redraw =1;    /* see below. */
  225.                 }
  226.             }
  227.         wmouse_location ();
  228.         }
  229.         /* continue loop until left is released.
  230.          */
  231.     while  ( (wmouse.wms_used & WMS_LEFT_RLS) == 0 ) ;
  232.  
  233.     wmouse.wms_internal = 0;
  234.  
  235.     wmouse_turn (OFF);
  236.  
  237.     /* redraw.
  238.      * The routine used to convert screen-->virtual 
  239.      * is not exactly the inverse of the routine that converts virtual->screen
  240.      *    
  241.      * Therefore if the mouse was used to drag the ptr, 
  242.      * the screen image of the ptr may be off by +-1 byte from 
  243.      *    where it's virtual value predicts.
  244.      * If needed, Remove it using screen co-ords,
  245.      *             redraw based on virtual co-ords.
  246.      */
  247.     if ( redraw )
  248.         {
  249.         wgoto ( xbar, oldy );
  250.         wputc ( IMAGE_BAR );
  251.         } 
  252.  
  253.     
  254.     /* At this pt, the onscreen ptr is invisible.
  255.      */
  256.      
  257.      
  258.      
  259.     /* Now see if either the up or the down icon was selected (release LEFT) 
  260.      */
  261.     if ( (y == y1) && (val > 0    ) )
  262.         {
  263.         /* released mouse on the UP_IMAGE icon
  264.          */
  265.         --val;
  266.         }
  267.  
  268.     if ( (y == y2) && (val < range) )
  269.         {
  270.         /* released mouse on the DN_IMAGE icon
  271.          */
  272.         ++val;
  273.         }
  274.  
  275.  
  276.     Bptr->Bscrollval = val;
  277.  
  278.     /* Now draw the final image of the ptr icon.
  279.      */
  280.     draw_ptr ( Bptr, IMAGE_PTR );
  281.  
  282.  
  283.     return (val);        /* wscrollbar_scroll() */
  284.     }
  285.  
  286.  
  287.  
  288. /*------------------------  END OF WSCRLLBR.C ---------------------------*/