home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 10.ddi / TVSRC.ZIP / TDESKTOP.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  5.8 KB  |  246 lines

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