home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tv20cpp.zip / src / TScrollBar.cpp < prev    next >
C/C++ Source or Header  |  1998-05-03  |  9KB  |  366 lines

  1. /*
  2.  * TScrollBar.cc
  3.  *
  4.  * Turbo Vision - Version 2.0
  5.  *
  6.  * Copyright (c) 1994 by Borland International
  7.  * All Rights Reserved.
  8.  *
  9.  * Modified by Sergio Sigala <ssigala@globalnet.it>
  10.  */
  11.  
  12. #define Uses_TKeys
  13. #define Uses_TScrollBar
  14. #define Uses_TRect
  15. #define Uses_TDrawBuffer
  16. #define Uses_TEvent
  17. #define Uses_TGroup
  18. #define Uses_opstream
  19. #define Uses_ipstream
  20. #include <tvision/tv.h>
  21.  
  22. #include <ctype.h>
  23. #include <string.h>
  24.  
  25. #define cpScrollBar  "\x04\x05\x05"
  26.  
  27. TScrollBar::TScrollBar( const TRect& bounds ) :
  28.     TView( bounds ),
  29.     value( 0 ),
  30.     minVal( 0 ),
  31.     maxVal( 0 ),
  32.     pgStep( 1 ),
  33.     arStep( 1 )
  34. {
  35.     if( size.x == 1 )
  36.         {
  37.         growMode = gfGrowLoX | gfGrowHiX | gfGrowHiY;
  38.         memcpy( chars, vChars, sizeof(vChars) );
  39.         }
  40.     else
  41.         {
  42.         growMode = gfGrowLoY | gfGrowHiX | gfGrowHiY;
  43.         memcpy( chars, hChars, sizeof(hChars) );
  44.         }
  45. }
  46.  
  47. void TScrollBar::draw()
  48. {
  49.     drawPos(getPos());
  50. }
  51.  
  52. void TScrollBar::drawPos( int pos )
  53. {
  54.     TDrawBuffer b;
  55.  
  56.     int s = getSize() - 1;
  57.     b.moveChar( 0, chars[0], getColor(2), 1 );
  58.     if( maxVal == minVal )
  59.         b.moveChar( 1, chars[4], getColor(1), s-1 );
  60.     else
  61.         {
  62.         b.moveChar( 1, chars[2], getColor(1), s-1 );
  63.         b.moveChar( pos, chars[3], getColor(3), 1 );
  64.         }
  65.  
  66.     b.moveChar( s, chars[1], getColor(2), 1 );
  67.     writeBuf( 0, 0, size.x, size.y, b );
  68. }
  69.  
  70. TPalette& TScrollBar::getPalette() const
  71. {
  72.     static TPalette palette( cpScrollBar, sizeof( cpScrollBar )-1 );
  73.     return palette;
  74. }
  75.  
  76. int TScrollBar::getPos()
  77. {
  78.     int r = maxVal - minVal;
  79.     if( r == 0 )
  80.         return 1;
  81.     else
  82.         return  int(( ((long(value - minVal) * (getSize() - 3)) + (r >> 1)) / r) + 1);
  83. }
  84.  
  85. int TScrollBar::getSize()
  86. {
  87.     int s;
  88.  
  89.     if( size.x == 1 )
  90.         s = size.y;
  91.     else
  92.         s = size.x;
  93.  
  94. #ifndef __UNPATCHED
  95.     return max( 2, s );
  96. #else
  97.     return max( 3, s );
  98. #endif
  99. }
  100.  
  101. static TPoint mouse;
  102. static int p, s;
  103. static TRect extent;
  104.  
  105. int TScrollBar::getPartCode()
  106. {
  107.     int part= - 1;
  108. #ifndef __UNPATCHED
  109.     if( extent.contains(mouse) )
  110.     {
  111.     int mark = (size.x == 1) ? mouse.y : mouse.x;
  112.  
  113.     // Check for vertical or horizontal size of 2
  114.     if((size.x == 1 && size.y == 2) || (size.x == 2 && size.y == 1))
  115.     {
  116.         // Set 'part' to left or right arrow only
  117.         if(mark < 1) part = sbLeftArrow;
  118.         else if(mark == p) part = sbRightArrow;
  119.     }
  120.     else
  121.     {
  122.         if (mark == p) part= sbIndicator;
  123.         else
  124.         {
  125.             if( mark < 1 ) part = sbLeftArrow;
  126.             else if( mark < p ) part= sbPageLeft;
  127.             else if( mark < s ) part= sbPageRight;
  128.             else part= sbRightArrow;
  129.             if( size.x == 1 ) part += 4;
  130.         }
  131.     }
  132.     }
  133. #else
  134.     if( extent.contains(mouse) )
  135.         {
  136.         int mark = (size.x == 1) ? mouse.y : mouse.x;
  137.  
  138.         if (mark == p)
  139.             part= sbIndicator;
  140.         else
  141.             {
  142.             if( mark < 1 )
  143.                 part = sbLeftArrow;
  144.             else if( mark < p )
  145.                 part= sbPageLeft;
  146.             else if( mark < s )
  147.                 part= sbPageRight;
  148.             else
  149.                 part= sbRightArrow;
  150.  
  151.             if( size.x == 1 )
  152.                 part += 4;
  153.             }
  154.         }
  155. #endif
  156.     return part;
  157. }
  158.  
  159. void TScrollBar::handleEvent( TEvent& event )
  160. {
  161.     Boolean Tracking;
  162. //    int i, clickPart;    /* XXX */
  163.     int i = 0, clickPart;    /* XXX */
  164.  
  165.     TView::handleEvent(event);
  166.     switch( event.what )
  167.         {
  168.         case evMouseDown:
  169.             message(owner, evBroadcast, cmScrollBarClicked,this); // Clicked()
  170.             mouse = makeLocal( event.mouse.where );
  171.             extent = getExtent();
  172.             extent.grow(1, 1);
  173.             p = getPos();
  174.             s = getSize() - 1;
  175.             clickPart= getPartCode();
  176.             if( clickPart != sbIndicator )
  177.                 {
  178.                 do  {
  179.                     mouse = makeLocal( event.mouse.where );
  180.                     if( getPartCode() == clickPart )
  181.                         setValue(value + scrollStep(clickPart) );
  182.                     } while( mouseEvent(event, evMouseAuto) );
  183.                 }
  184.             else
  185.                 {
  186.                 do  {
  187.                     mouse = makeLocal( event.mouse.where );
  188.                     Tracking = extent.contains(mouse);
  189.                     if( Tracking )
  190.                         {
  191.                         if( size.x == 1 )
  192.                             i = mouse.y;
  193.                         else
  194.                             i = mouse.x;
  195.                         i = max( i, 1 );
  196.                         i = min( i, s-1 );
  197.                         }
  198.                     else
  199.                         i = getPos();
  200.                     if(i != p )
  201.                         {
  202.                         drawPos(i);
  203. #ifndef __UNPATCHED
  204.             // nothing
  205. #else
  206.                         p = i;
  207. #endif
  208.                         }
  209.                     } while( mouseEvent(event,evMouseMove) );
  210.                 if( Tracking && s > 2 )
  211.                     {
  212.                     s -= 2;
  213.                     setValue( int(((long(p - 1) * (maxVal - minVal) + (s >> 1)) / s) + minVal));
  214.                     }
  215.                 }
  216.             clearEvent(event);
  217.             break;
  218.         case  evKeyDown:
  219.             if( (state & sfVisible) != 0 )
  220.                 {
  221.                 clickPart = sbIndicator;
  222.                 if( size.y == 1 )
  223.                     switch( ctrlToArrow(event.keyDown.keyCode) )
  224.                         {
  225.                         case kbLeft:
  226.                             clickPart = sbLeftArrow;
  227.                             break;
  228.                         case kbRight:
  229.                             clickPart = sbRightArrow;
  230.                             break;
  231.                         case kbCtrlLeft:
  232.                             clickPart = sbPageLeft;
  233.                             break;
  234.                         case kbCtrlRight:
  235.                             clickPart = sbPageRight;
  236.                             break;
  237.                         case kbHome:
  238.                             i = minVal;
  239.                             break;
  240.                         case kbEnd:
  241.                             i = maxVal;
  242.                             break;
  243.                         default:
  244.                             return;
  245.                         }
  246.                 else
  247.                     switch( ctrlToArrow(event.keyDown.keyCode) )
  248.                         {
  249.                         case kbUp:
  250.                             clickPart = sbUpArrow;
  251.                             break;
  252.                         case kbDown:
  253.                             clickPart = sbDownArrow;
  254.                             break;
  255.                         case kbPgUp:
  256.                             clickPart = sbPageUp;
  257.                             break;
  258.                         case kbPgDn:
  259.                             clickPart = sbPageDown;
  260.                             break;
  261.                         case kbCtrlPgUp:
  262.                             i = minVal;
  263.                             break;
  264.                         case kbCtrlPgDn:
  265.                             i = maxVal;
  266.                             break;
  267.                         default:
  268.                             return;
  269.                         }
  270.                 message(owner,evBroadcast,cmScrollBarClicked,this); // Clicked
  271.                 if( clickPart != sbIndicator )
  272.                     i = value + scrollStep(clickPart);
  273.                 setValue(i);
  274.                 clearEvent(event);
  275.                 }
  276.         }
  277. }
  278.  
  279. void TScrollBar::scrollDraw()
  280. {
  281.     message(owner, evBroadcast, cmScrollBarChanged,this);
  282. }
  283.  
  284. int TScrollBar::scrollStep( int part )
  285. {
  286.     int  step;
  287.  
  288.     if( !(part & 2) )
  289.         step = arStep;
  290.     else
  291.         step = pgStep;
  292.     if( !(part & 1) )
  293.         return -step;
  294.     else
  295.         return step;
  296. }
  297.  
  298. void TScrollBar::setParams( int aValue,
  299.                             int aMin,
  300.                             int aMax,
  301.                             int aPgStep,
  302.                             int aArStep
  303.                           )
  304. {
  305.  int  sValue;
  306.  
  307.     aMax = max( aMax, aMin );
  308.     aValue = max( aMin, aValue );
  309.     aValue = min( aMax, aValue );
  310.     sValue = value;
  311.     if( sValue != aValue || minVal != aMin || maxVal != aMax )
  312.         {
  313.         value = aValue;
  314.         minVal = aMin;
  315.         maxVal = aMax;
  316.         drawView();
  317.         if( sValue != aValue )
  318.             scrollDraw();
  319.         }
  320.     pgStep = aPgStep;
  321.     arStep = aArStep;
  322. }
  323.  
  324. void TScrollBar::setRange( int aMin, int aMax )
  325. {
  326.     setParams( value, aMin, aMax, pgStep, arStep );
  327. }
  328.  
  329. void TScrollBar::setStep( int aPgStep, int aArStep )
  330. {
  331.     setParams( value, minVal, maxVal, aPgStep, aArStep );
  332. }
  333.  
  334. void TScrollBar::setValue( int aValue )
  335. {
  336.     setParams( aValue, minVal, maxVal, pgStep, arStep );
  337. }
  338.  
  339. #if !defined(NO_STREAMABLE)
  340.  
  341. void TScrollBar::write( opstream& os )
  342. {
  343.     TView::write( os );
  344.     os << value << minVal << maxVal << pgStep << arStep;
  345.     os.writeBytes(chars, sizeof(chars));
  346. }
  347.  
  348. void *TScrollBar::read( ipstream& is )
  349. {
  350.     TView::read( is );
  351.     is >> value >> minVal >> maxVal >> pgStep >> arStep;
  352.     is.readBytes(chars, sizeof(TScrollChars));
  353.     return this;
  354. }
  355.  
  356. TStreamable *TScrollBar::build()
  357. {
  358.     return new TScrollBar( streamableInit );
  359. }
  360.  
  361. TScrollBar::TScrollBar( StreamableInit ) : TView( streamableInit )
  362. {
  363. }
  364.  
  365. #endif
  366.