home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tv20os2.zip / src / TCluster.cpp < prev    next >
C/C++ Source or Header  |  1999-05-26  |  10KB  |  465 lines

  1. /*
  2.  * TCluster.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_TCluster
  14. #define Uses_TDrawBuffer
  15. #define Uses_TEvent
  16. #define Uses_TPoint
  17. #define Uses_TSItem
  18. #define Uses_TStringCollection
  19. #define Uses_TGroup
  20. #define Uses_opstream
  21. #define Uses_ipstream
  22. #include <tvision/tv.h>
  23.  
  24. #include <ctype.h>
  25. #include <string.h>
  26.  
  27. #ifndef __UNPATCHED
  28. #define cpCluster "\x10\x11\x12\x12\x1f"
  29. #else
  30. #define cpCluster "\x10\x11\x12\x12\1f"
  31. #endif
  32.  
  33. TCluster::TCluster( const TRect& bounds, TSItem *aStrings ) :
  34.     TView(bounds),
  35.     value( 0 ),
  36.     sel( 0 )
  37. {
  38.     options |= ofSelectable | ofFirstClick | ofPreProcess | ofPostProcess;
  39.     short i = 0;
  40.     TSItem *p;
  41.     for( p = aStrings; p != 0; p = p->next )
  42.         i++;
  43.  
  44.     strings = new TStringCollection( i, 0 );
  45.  
  46.     while( aStrings != 0 )
  47.         {
  48.         p = aStrings;
  49.         strings->atInsert( strings->getCount(), newStr(aStrings->value) );
  50.         aStrings = aStrings->next;
  51.         delete p;
  52.         }
  53.  
  54.     setCursor( 2, 0 );
  55.     showCursor();
  56.     enableMask = 0xFFFFFFFFL;
  57. }
  58.  
  59. TCluster::~TCluster()
  60. {
  61.     destroy( (TCollection *)strings );
  62. }
  63.  
  64. ushort  TCluster::dataSize()
  65. {
  66.      // value is now a long, but for compatibility with earlier TV,
  67.      // return size of short; TMultiCheckBoxes returns sizeof(long).
  68.  
  69.     return sizeof(short);
  70. }
  71.  
  72. void TCluster::drawBox( const char *icon, char marker)
  73. {
  74.     char s[3];
  75.     s[0]=' '; s[1]=marker; s[2]=0;
  76.     drawMultiBox(icon, s);
  77. }
  78.  
  79. void TCluster::drawMultiBox( const char *icon, const char* marker)
  80. {
  81.     TDrawBuffer b;
  82.     ushort color;
  83.     int i, j, cur;
  84.  
  85.     ushort cNorm = getColor( 0x0301 );
  86.     ushort cSel = getColor( 0x0402 );
  87.     ushort cDis = getColor( 0x0505 );
  88.     for( i = 0; i <= size.y; i++ )
  89.     {
  90.         b.moveChar(0, ' ',(uchar)cNorm, size.x);
  91.         for( j = 0; j <= (strings->getCount()-1)/size.y + 1; j++ )
  92.         {
  93.             cur = j * size.y + i;
  94.             if( cur < strings->getCount() )
  95.             {
  96.                 int col = column( cur );
  97.  
  98.                 if ( ((col+strlen((const char*)strings->at(cur))+5) <
  99.                     (sizeof(b)/sizeof(ushort))) &&  (col < size.x))
  100.                 {
  101.                     if(!buttonState( cur ))
  102.                         color = cDis;
  103.                     else if( (cur == sel) && (state & sfSelected) != 0 )
  104.                         color = cSel;
  105.                     else
  106.                         color = cNorm;
  107.                     b.moveChar( col, ' ', color, size.x - col );
  108.                     b.moveCStr( col, icon, color );
  109.  
  110.                     b.putChar(col+2, marker[multiMark(cur)]);
  111.                     b.moveCStr( col+5, (char *)(strings->at(cur)), color );
  112.                     if(showMarkers && ((state & sfSelected) != 0) && cur==sel)
  113.                     {
  114.                         b.putChar( col, specialChars[0] );
  115.                         b.putChar( column(cur+size.y)-1, specialChars[1] );
  116.                     }
  117.  
  118.                 }
  119.             }
  120.         }
  121.         writeBuf( 0, i, size.x, 1, b );
  122.     }
  123.     setCursor( column(sel)+2, row(sel) );
  124. }
  125.  
  126. void TCluster::getData(void * rec)
  127. {
  128.     *(ushort*)rec = value;
  129.     drawView();
  130. }
  131.  
  132. ushort TCluster::getHelpCtx()
  133. {
  134.     if( helpCtx == hcNoContext )
  135.         return hcNoContext;
  136.     else
  137.         return helpCtx + sel;
  138. }
  139.  
  140. TPalette& TCluster::getPalette() const
  141. {
  142.     static TPalette palette( cpCluster, sizeof( cpCluster )-1 );
  143.     return palette;
  144. }
  145.  
  146. void TCluster::moveSel(int i, int s)
  147. {
  148.   if (i <= strings->getCount())
  149.   {
  150.         sel = s;
  151.         movedTo(sel);
  152.         drawView();
  153.   }
  154. }
  155.  
  156. void TCluster::handleEvent( TEvent& event )
  157. {
  158.     TView::handleEvent(event);
  159.     if (!(options & ofSelectable))
  160.         return;
  161.     if( event.what == evMouseDown )
  162.         {
  163.         TPoint mouse = makeLocal( event.mouse.where );
  164.         int i = findSel(mouse);
  165.         if( (i != -1) && buttonState(i))
  166.             sel = i;
  167.         drawView();
  168.         do  {
  169.             mouse = makeLocal( event.mouse.where );
  170.             if( (findSel(mouse) == sel ) && buttonState(sel))
  171.                 showCursor();
  172.             else
  173.                 hideCursor();
  174.             } while( mouseEvent(event,evMouseMove) );
  175.         showCursor();
  176.         mouse = makeLocal( event.mouse.where );
  177.         if( findSel(mouse) == sel )
  178.             {
  179.             press(sel);
  180.             drawView();
  181.             }
  182.         clearEvent(event);
  183.         }
  184.     else if( event.what == evKeyDown )
  185.     {
  186.     int s = sel;
  187.         switch (ctrlToArrow(event.keyDown.keyCode))
  188.             {
  189.             case kbUp:
  190.                 if( (state & sfFocused) != 0 )
  191.                     {
  192.             int i = 0;
  193.             do {
  194.                 i++; s--;
  195.                 if (s < 0)
  196.                     s = strings->getCount()-1;
  197.             } while (!(buttonState(s) || (i > strings->getCount())));
  198.             moveSel(i, s);
  199.             clearEvent(event);
  200.                     }
  201.                 break;
  202.  
  203.             case kbDown:
  204.                 if( (state & sfFocused) != 0 )
  205.                     {
  206.             int i = 0;
  207.             do {
  208.                 i++; s++;
  209.                 if (s >= strings->getCount())
  210.                     s = 0;
  211.              } while (!(buttonState(s) || (i > strings->getCount())));
  212.              moveSel(i, s);
  213.              clearEvent(event);
  214.                      }
  215.                 break;
  216.             case kbRight:
  217.                 if( (state & sfFocused) != 0 )
  218.                     {
  219.             int i = 0;
  220.             do {
  221.                             i++; s += size.y;
  222. #ifndef __UNPATCHED
  223.                 if (s >= strings->getCount() )    // BUG FIX - EFW - 10/25/94
  224.                 {
  225.                 s = (s +  1) % size.y;
  226.                 if( s >= strings->getCount() )
  227.                     s =  0;
  228.                 }
  229. #else
  230.                 if (s >= strings->getCount() )
  231.                 s = 0;
  232. #endif
  233.             } while (!(buttonState(s) || (i > strings->getCount())));
  234. #ifndef __UNPATCHED
  235.             moveSel(i, s);    // BUG FIX - EFW - 10/25/94
  236. #endif
  237.                     clearEvent(event);
  238.                     }
  239.                 break;
  240.             case kbLeft:
  241.                 if( (state & sfFocused) != 0 )
  242.                     {
  243.                 int i = 0;
  244.             do {
  245.                 i++;
  246.                 if ( s > 0 )
  247.                 {
  248.                     s -= size.y;
  249.                     if ( s < 0 )
  250.                     {
  251.                         s=((strings->getCount()+size.y-1)/
  252.                             size.y)*size.y + s - 1;
  253.                         if( s >= strings->getCount() )
  254.                             s = strings->getCount()-1;
  255.                     }
  256.                 }
  257.                 else
  258.                     s = strings->getCount()-1;
  259.  
  260.             } while (!(buttonState(s) || (i > strings->getCount())));
  261.  
  262.                     clearEvent(event);
  263.                     }
  264.                 break;
  265.             default:
  266.                 for( int i = 0; i < strings->getCount(); i++ )
  267.                     {
  268.                     char c = hotKey( (char *)(strings->at(i)) );
  269.                     char cpchar;
  270.                     if( hab != NULLHANDLE )
  271.                         cpchar = WinUpperChar( hab, Codepage, Country, event.keyDown.charScan.charCode );
  272.                      else
  273.                            cpchar = toupper(event.keyDown.charScan.charCode);
  274.                     if( getAltCode(c) == event.keyDown.keyCode || ( ( owner->phase == phPostProcess || (state & sfFocused) != 0 ) && c != 0 && cpchar == c ) )
  275.                         {
  276.                                 if (buttonState(i))
  277.                                     {
  278.                                     if ( focus())
  279.                                         {
  280.                                         sel = i;
  281.                                         movedTo(sel);
  282.                                         press(sel);
  283.                                         drawView();
  284.                                         }
  285.                                     clearEvent(event);
  286.                                     }
  287.                                 return;
  288.                                 }
  289.                     }
  290.                 if( event.keyDown.charScan.charCode == ' ' &&
  291.                     (state & sfFocused) != 0
  292.                   )
  293.                     {
  294.                     press(sel);
  295.                     drawView();
  296.                     clearEvent(event);
  297.                     }
  298.             }
  299.     }
  300. }
  301.  
  302.  
  303. void TCluster::setButtonState(unsigned long aMask, Boolean enable)
  304. {
  305.     if (!enable)
  306.         enableMask &= ~aMask;
  307.     else
  308.         enableMask |= aMask;
  309.  
  310.     int n = strings->getCount();
  311.     if ( n < 32 )
  312.     {
  313.         unsigned long testMask = (1 << n) - 1;
  314.         if ((enableMask & testMask) != 0)
  315.             options |= ofSelectable;
  316.         else
  317.             options &= ~ofSelectable;
  318.     }
  319. }
  320.  
  321.  
  322. void TCluster::setData(void * rec)
  323. {
  324.     value =  *(ushort *)rec;
  325.     drawView();
  326. }
  327.  
  328. void TCluster::setState( ushort aState, Boolean enable )
  329. {
  330.     TView::setState( aState, enable );
  331.     if( aState == sfSelected )
  332. #ifndef __UNPATCHED
  333.       {
  334.         int i = 0, s = sel - 1;
  335.     do {
  336.           i++;
  337.           s++;
  338.           if(s >= strings->getCount())
  339.           s = 0;
  340.           } while( !(buttonState(s) || i > strings->getCount()) );
  341.  
  342.         moveSel(i, s);
  343.       }
  344. #endif
  345.         drawView();
  346. }
  347.  
  348. Boolean TCluster::mark( int )
  349. {
  350.     return False;
  351. }
  352.  
  353. uchar TCluster::multiMark( int item )
  354. {
  355.     return (uchar)(mark(item)==True);
  356. }
  357.  
  358. void TCluster::movedTo( int )
  359. {
  360. }
  361.  
  362. void TCluster::press( int )
  363. {
  364. }
  365.  
  366. int TCluster::column( int item )
  367. {
  368.     if( item < size.y )
  369.         return 0;
  370.     else
  371.         {
  372.         int width = 0;
  373.         int col = -6;
  374.         int l = 0;
  375.         for( int i = 0; i <= item; i++ )
  376.             {
  377.             if( i % size.y == 0 )
  378.                 {
  379.                 col += width + 6;
  380.                 width = 0;
  381.                 }
  382.  
  383.             if( i < strings->getCount() )
  384.                 l = cstrlen( (char *)(strings->at(i)) );
  385.             if( l > width )
  386.                 width = l;
  387.             }
  388.         return col;
  389.         }
  390. }
  391.  
  392. int TCluster::findSel( TPoint p )
  393. {
  394.     TRect r = getExtent();
  395.     if( !r.contains(p) )
  396.         return -1;
  397.     else
  398.         {
  399.         int i = 0;
  400.         while( p.x >= column( i + size.y ) )
  401.             i += size.y;
  402.         int s = i + p.y;
  403.         if( s >= strings->getCount() )
  404.             return -1;
  405.         else
  406.             return s;
  407.         }
  408. }
  409.  
  410. int TCluster::row( int item )
  411. {
  412.     return item % size.y;
  413. }
  414.  
  415. Boolean TCluster::buttonState(int item)
  416. {
  417.     if (item < 32)
  418.     {
  419.         unsigned long mask = 1;
  420.  
  421.         while (item--)
  422.             mask <<= 1;
  423.  
  424.         if (enableMask & mask)
  425.             return True;
  426.         else
  427.             return False;
  428.     }
  429.     else
  430.         return False;
  431. }
  432.  
  433.  
  434. #if !defined(NO_STREAMABLE)
  435.  
  436.  
  437. void TCluster::write( opstream& os )
  438. {
  439.     TView::write( os );
  440.     os << value << sel << enableMask << strings;
  441. }
  442.  
  443. void *TCluster::read( ipstream& is )
  444. {
  445.     TView::read( is );
  446.     is >> value >> sel >> enableMask >> strings;
  447.  
  448.     setCursor( 2, 0 );
  449.     showCursor();
  450.     setButtonState(0,True);
  451.     return this;
  452. }
  453.  
  454. TStreamable *TCluster::build()
  455. {
  456.     return new TCluster( streamableInit );
  457. }
  458.  
  459. TCluster::TCluster( StreamableInit ) : TView( streamableInit )
  460. {
  461. }
  462.  
  463.  
  464. #endif
  465.