home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / code / wxwin140 / src / sb_scrol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  6.5 KB  |  271 lines

  1. #ifndef lint
  2. #ifdef sccs
  3. static char     sccsid[] = "@(#)sb_scroll.c 1.40 91/09/14";
  4. #endif
  5. #endif
  6.  
  7. /*
  8.  *    (c) Copyright 1989 Sun Microsystems, Inc. Sun design patents 
  9.  *    pending in the U.S. and foreign countries. See LEGAL NOTICE 
  10.  *    file for terms of the license.
  11.  */
  12.  
  13. /*
  14.  * Module:    sb_scroll.c
  15.  * 
  16.  * Description:
  17.  * 
  18.  * Maps events into actions
  19.  * 
  20.  */
  21.  
  22.  
  23. /*
  24.  * Include files:
  25.  */
  26.  
  27. #include <xview_private/sb_impl.h>
  28. #include <xview/win_notify.h>
  29.  
  30. /*
  31.  * Declaration of Functions Defined in This File (in order):
  32.  */
  33. Xv_public void  scrollbar_default_compute_scroll_proc();
  34.  
  35. Pkg_private int scrollbar_scroll();
  36. Pkg_private int scrollbar_scroll_to_offset();
  37.  
  38. static int      scrollbar_offset_to_client_units();
  39. static unsigned long scrollbar_absolute_offset();
  40.  
  41.  
  42. /******************************************************************/
  43.  
  44. Pkg_private int
  45. scrollbar_scroll(sb, pos, motion)
  46.     Xv_scrollbar_info *sb;
  47.     int             pos;
  48.     Scroll_motion   motion;
  49. {
  50.     long unsigned   voffset = 0, vstart = 0;
  51.     int             result = SCROLLBAR_POSITION_UNCHANGED;
  52.     int             available_cable;
  53.  
  54.     if (motion == SCROLLBAR_NONE)
  55.     return (result);
  56.  
  57.     /* translate position into client space */
  58.     available_cable = scrollbar_available_cable(sb);
  59.  
  60.     if (sb->compute_scroll_proc != NULL) {
  61.     sb->compute_scroll_proc(SCROLLBAR_PUBLIC(sb), pos, available_cable,
  62.                 motion, &voffset, &sb->object_length);
  63.     }
  64.     if (sb->normalize_proc != NULL) {
  65.     sb->normalize_proc(SCROLLBAR_PUBLIC(sb), voffset, motion, &vstart);
  66.     } else {
  67.     vstart = voffset;
  68.     }
  69.  
  70.     if (vstart != sb->view_start) {
  71.     result = scrollbar_scroll_to_offset(sb, vstart);
  72.     }
  73.     scrollbar_position_elevator(sb, sb->painted, motion);
  74.  
  75.     return (result);
  76. }
  77.  
  78. Pkg_private int
  79. scrollbar_scroll_to_offset(sb, view_start)
  80.     Xv_scrollbar_info *sb;
  81.     long unsigned   view_start;
  82. {
  83.     extern Notify_arg win_copy_event();
  84.     extern void     win_free_event();
  85.  
  86.     /* do bounds checking */
  87.     if (sb->view_length > sb->object_length)
  88.       view_start = 0;
  89.     else if (view_start > sb->object_length) {
  90.     view_start = sb->object_length;
  91.     } else if (view_start < 0) {
  92.     view_start = 0;
  93.     }
  94.     if (view_start != sb->view_start) {
  95.  
  96.     sb->last_view_start = sb->view_start;
  97.     sb->view_start = view_start;
  98.  
  99.     (void) win_post_id_and_arg(sb->managee,
  100.                    SCROLLBAR_REQUEST, NOTIFY_IMMEDIATE,
  101.                    SCROLLBAR_PUBLIC(sb), win_copy_event,
  102.                    win_free_event);
  103.     return (XV_OK);
  104.     } else {
  105.     return (SCROLLBAR_POSITION_UNCHANGED);
  106.     }
  107. }
  108.  
  109. Xv_public void
  110. scrollbar_default_compute_scroll_proc(scroll_public, pos, length, motion,
  111.                       offset, object_length)
  112.     Scrollbar       scroll_public;
  113.     int             pos;
  114.     int             length;
  115.     Scroll_motion   motion;
  116.     unsigned long  *offset;
  117.     unsigned long  *object_length;
  118. {
  119.     Xv_scrollbar_info *sb = SCROLLBAR_PRIVATE(scroll_public);
  120.     int             minus_movement;
  121.     unsigned long   pixel_offset;
  122.  
  123.     pixel_offset = sb->view_start * sb->pixels_per_unit;
  124.  
  125.     switch (motion) {
  126.       case SCROLLBAR_ABSOLUTE:
  127.     /* pos is position in the cable */
  128.     pixel_offset = scrollbar_absolute_offset(sb, pos, length);
  129.     break;
  130.  
  131.       case SCROLLBAR_POINT_TO_MIN:
  132.     pixel_offset += (pos - sb->pixels_per_unit);
  133.     break;
  134.  
  135.       case SCROLLBAR_PAGE_FORWARD:
  136.     if (sb->page_length != SCROLLBAR_DEFAULT_LENGTH) {
  137.         /* page scrolling */
  138.         pixel_offset += (sb->page_length * sb->pixels_per_unit);
  139.     } else {
  140.         /* display scrolling */
  141.         pixel_offset += (sb->view_length * sb->pixels_per_unit);
  142.     }
  143.     break;
  144.  
  145.       case SCROLLBAR_LINE_FORWARD:
  146.     pixel_offset += sb->pixels_per_unit;
  147.     break;
  148.  
  149.       case SCROLLBAR_MIN_TO_POINT:
  150.     if (pos > pixel_offset) {
  151.         *offset = 0;
  152.     } else {
  153.         pixel_offset -= (pos - sb->pixels_per_unit);
  154.     }
  155.     break;
  156.  
  157.       case SCROLLBAR_PAGE_BACKWARD:
  158.     if (sb->page_length != SCROLLBAR_DEFAULT_LENGTH) {
  159.         /* page scrolling */
  160.         minus_movement = sb->page_length * sb->pixels_per_unit;
  161.     } else {
  162.         /* display scrolling */
  163.         minus_movement = sb->view_length * sb->pixels_per_unit;
  164.     }
  165.     if (minus_movement > pixel_offset) {
  166.         pixel_offset = 0;
  167.     } else {
  168.         pixel_offset -= minus_movement;
  169.     }
  170.     break;
  171.  
  172.       case SCROLLBAR_LINE_BACKWARD:
  173.     if (sb->pixels_per_unit > pixel_offset) {
  174.         pixel_offset = 0;
  175.     } else {
  176.         pixel_offset -= sb->pixels_per_unit;
  177.     }
  178.     break;
  179.  
  180.       case SCROLLBAR_TO_END:
  181.     pixel_offset = Max_offset(sb) * sb->pixels_per_unit;
  182.     break;
  183.  
  184.       case SCROLLBAR_TO_START:
  185.     pixel_offset = 0;
  186.     break;
  187.  
  188.       default:
  189.     break;
  190.     }
  191.  
  192.     scrollbar_offset_to_client_units(sb, pixel_offset, motion, offset);
  193.     *object_length = sb->object_length;
  194. }
  195.  
  196. static int
  197. scrollbar_offset_to_client_units(sb, pixel_offset, motion, view_start)
  198.     Xv_scrollbar_info *sb;
  199.     long unsigned   pixel_offset;
  200.     Scroll_motion   motion;
  201.     long unsigned  *view_start;     /* RETURN */
  202. {
  203.     *view_start = sb->view_start;
  204.  
  205.     switch (motion) {
  206.       case SCROLLBAR_ABSOLUTE:
  207.       case SCROLLBAR_MIN_TO_POINT:
  208.       case SCROLLBAR_TO_END:
  209.       case SCROLLBAR_TO_START:
  210.       case SCROLLBAR_LINE_FORWARD:
  211.       case SCROLLBAR_LINE_BACKWARD:
  212.     *view_start  = pixel_offset / sb->pixels_per_unit;
  213.     break;
  214.  
  215.       case SCROLLBAR_POINT_TO_MIN:
  216.     *view_start = ((pixel_offset % sb->pixels_per_unit) == 0) ? 
  217.                     pixel_offset / sb->pixels_per_unit : 
  218.                 pixel_offset / sb->pixels_per_unit + 1;
  219.     break;
  220.  
  221.       case SCROLLBAR_PAGE_BACKWARD:
  222.     if (sb->page_length != SCROLLBAR_DEFAULT_LENGTH && sb->page_length != 0) {
  223.  
  224.         long unsigned pixels_per_page = sb->pixels_per_unit * sb->page_length;
  225.         long unsigned page = pixel_offset / pixels_per_page;
  226.         
  227.         /* If not on a page boundary round up */
  228.         if ( (page * pixels_per_page) != pixel_offset )
  229.           page++;
  230.         
  231.         *view_start = page * sb->page_length;
  232.     } else {
  233.         *view_start = pixel_offset / sb->pixels_per_unit;
  234.     }
  235.     break;
  236.  
  237.       case SCROLLBAR_PAGE_FORWARD:
  238.     if (sb->page_length != SCROLLBAR_DEFAULT_LENGTH && sb->page_length != 0) {
  239.  
  240.         long unsigned pixels_per_page = sb->pixels_per_unit * sb->page_length;
  241.         long unsigned page = pixel_offset / pixels_per_page;
  242.         
  243.         *view_start = page * sb->page_length;
  244.     } else {
  245.         *view_start = pixel_offset / sb->pixels_per_unit;
  246.     }
  247.     break;
  248.  
  249.       default:
  250.     break;
  251.     }
  252.  
  253.     if ( *view_start > Max_offset(sb) )
  254.       *view_start = Max_offset(sb);
  255.  
  256.     return (XV_OK);
  257. }
  258.  
  259.  
  260. static unsigned long
  261. scrollbar_absolute_offset(sb, pos, length)
  262.     Xv_scrollbar_info *sb;
  263.     int             pos;
  264.     int             length;
  265. {
  266.     if (length <= 0)
  267.     return (0);
  268.     else
  269.     return (Max_offset(sb) * pos / length * sb->pixels_per_unit);
  270. }
  271.