home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tv20os2.zip / src / TDeskTop.cpp < prev    next >
C/C++ Source or Header  |  1998-01-19  |  5KB  |  259 lines

  1. /*
  2.  * TDeskTop.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_TDeskTop
  13. #define Uses_TRect
  14. #define Uses_TPoint
  15. #define Uses_TEvent
  16. #define Uses_TBackground
  17. #define Uses_opstream
  18. #define Uses_ipstream
  19. #include <tvision/tv.h>
  20.  
  21. #include <stdlib.h>
  22.  
  23. TDeskInit::TDeskInit( TBackground *(*cBackground)( TRect ) ) :
  24.     createBackground( cBackground )
  25. {
  26. }
  27.  
  28. TDeskTop::TDeskTop( const TRect& bounds ) :
  29.     TGroup(bounds),
  30.     TDeskInit( &TDeskTop::initBackground )
  31. {
  32.     growMode = gfGrowHiX | gfGrowHiY;
  33.     tileColumnsFirst = False;
  34.  
  35.     if( createBackground != 0 && (background = createBackground( getExtent() )) != 0 )
  36.         insert( background );
  37. }
  38.  
  39. void TDeskTop::shutDown()
  40. {
  41.     background = 0;
  42.     TGroup::shutDown();
  43. }
  44.  
  45. inline Boolean Tileable( TView *p )
  46. {
  47.     return Boolean( (p->options & ofTileable) != 0 && (p->state & sfVisible) != 0 );
  48. }
  49.  
  50. static short cascadeNum;
  51. static TView *lastView;
  52.  
  53. void doCount( TView* p, void * )
  54. {
  55.     if( Tileable( p ) )
  56.         {
  57.         cascadeNum++;
  58.         lastView = p;
  59.         }
  60. }
  61.  
  62. void doCascade( TView* p, void *r )
  63. {
  64.     if( Tileable( p ) && cascadeNum >= 0 )
  65.         {
  66.         TRect NR = *(TRect *)r;
  67.         NR.a.x += cascadeNum;
  68.         NR.a.y += cascadeNum;
  69.         p->locate( NR );
  70.         cascadeNum--;
  71.         }
  72. }
  73.  
  74. void TDeskTop::cascade( const TRect &r )
  75. {
  76.     TPoint min, max;
  77.     cascadeNum = 0;
  78.     forEach( doCount, 0 );
  79.     if( cascadeNum > 0 )
  80.         {
  81.         lastView->sizeLimits( min, max );
  82.         if( (min.x > r.b.x - r.a.x - cascadeNum) ||
  83.             (min.y > r.b.y - r.a.y - cascadeNum) )
  84.             tileError();
  85.         else
  86.             {
  87.             cascadeNum--;
  88.             lock();
  89.             forEach( doCascade, (void *)&r );
  90.             unlock();
  91.             }
  92.         }
  93. }
  94.  
  95. void TDeskTop::handleEvent(TEvent& event)
  96. {
  97.     TGroup::handleEvent( event );
  98.     if( event.what == evCommand )
  99.         {
  100.         switch( event.message.command )
  101.             {
  102.             case cmNext:
  103. #ifndef __UNPATCHED
  104.                 if(valid(cmReleasedFocus))      // <-- Check valid.
  105.                     selectNext( False );
  106. #else
  107.                 selectNext( False );
  108. #endif
  109.                 break;
  110.             case cmPrev:
  111. #ifndef __UNPATCHED
  112.                 if(valid(cmReleasedFocus))      // <-- Check valid.
  113.                     current->putInFrontOf( background );
  114. #else
  115.                 current->putInFrontOf( background );
  116. #endif
  117.                 break;
  118.             default:
  119.                 return;
  120.             }
  121.         clearEvent( event );
  122.         }
  123. }
  124.  
  125. TBackground *TDeskTop::initBackground( TRect r )
  126. {
  127.     return new TBackground( r, defaultBkgrnd );
  128. }
  129.  
  130. short iSqr( short i )
  131. {
  132.     short res1 = 2;
  133.     short res2 = i/res1;
  134.     while( abs( (int)(res1 - res2) ) > 1 )
  135.         {
  136.         res1 = (res1 + res2)/2;
  137.         res2 = i/res1;
  138.         }
  139.     return res1 < res2 ? res1 : res2;
  140. }
  141.  
  142. void mostEqualDivisors(short n, short& x, short& y, Boolean favorY)
  143. {
  144.     short  i;
  145.  
  146.     i = iSqr( n );
  147.     if( n % i != 0 )
  148.         if( n % (i+1) == 0 )
  149.             i++;
  150.     if( i < (n/i) )
  151.         i = n/i;
  152.  
  153.     if (favorY)
  154.         {
  155.         x = n/i;
  156.         y = i;
  157.         }
  158.     else
  159.         {
  160.         y = n/i;
  161.         x = i;
  162.         }
  163. }
  164.  
  165. static short numCols, numRows, numTileable, leftOver, tileNum;
  166.  
  167. void doCountTileable( TView* p, void * )
  168. {
  169.     if( Tileable( p ) )
  170.         numTileable++;
  171. }
  172.  
  173. int dividerLoc( int lo, int hi, int num, int pos)
  174. {
  175.     return int(long(hi-lo)*pos/long(num)+lo);
  176. }
  177.  
  178. TRect calcTileRect( short pos, const TRect &r )
  179. {
  180.     short x, y;
  181.     TRect nRect;
  182.  
  183.     short d = (numCols - leftOver) * numRows;
  184.     if( pos <  d )
  185.         {
  186.         x = pos / numRows;
  187.         y = pos % numRows;
  188.         }
  189.     else
  190.         {
  191.         x = (pos-d)/(numRows+1) + (numCols-leftOver);
  192.         y = (pos-d)%(numRows+1);
  193.         }
  194.     nRect.a.x = dividerLoc( r.a.x, r.b.x, numCols, x );
  195.     nRect.b.x = dividerLoc( r.a.x, r.b.x, numCols, x+1 );
  196.     if( pos >= d )
  197.         {
  198.         nRect.a.y = dividerLoc(r.a.y, r.b.y, numRows+1, y);
  199.         nRect.b.y = dividerLoc(r.a.y, r.b.y, numRows+1, y+1);
  200.         }
  201.     else
  202.         {
  203.         nRect.a.y = dividerLoc(r.a.y, r.b.y, numRows, y);
  204.         nRect.b.y = dividerLoc(r.a.y, r.b.y, numRows, y+1);
  205.         }
  206.     return nRect;
  207. }
  208.  
  209. void doTile( TView* p, void *lR )
  210. {
  211.     if( Tileable( p ) )
  212.         {
  213.         TRect r = calcTileRect( tileNum, *(const TRect *)lR );
  214.         p->locate(r);
  215.         tileNum--;
  216.         }
  217. }
  218.  
  219. void TDeskTop::tile( const TRect& r )
  220. {
  221.     numTileable =  0;
  222.     forEach( doCountTileable, 0 );
  223.     if( numTileable > 0 )
  224.         {
  225.         mostEqualDivisors( numTileable, numCols, numRows, Boolean( !tileColumnsFirst ));
  226.         if( ( (r.b.x - r.a.x)/numCols ==  0 ) ||
  227.             ( (r.b.y - r.a.y)/numRows ==  0) )
  228.             tileError();
  229.         else
  230.             {
  231.             leftOver = numTileable % numCols;
  232.             tileNum = numTileable - 1;
  233.             lock();
  234.             forEach( doTile, (void *)&r );
  235.             unlock();
  236.             }
  237.         }
  238. }
  239.  
  240. void  TDeskTop::tileError()
  241. {
  242. }
  243.  
  244. #if !defined(NO_STREAMABLE)
  245.  
  246. TStreamable *TDeskTop::build()
  247. {
  248.     return new TDeskTop( streamableInit );
  249. }
  250.  
  251. TDeskTop::TDeskTop( StreamableInit ) :
  252.     TGroup( streamableInit ),
  253.     TDeskInit( 0 /*streamableInit*/ )
  254. {
  255.     tileColumnsFirst = False;
  256. }
  257.  
  258. #endif
  259.