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

  1. /*------------------------------------------------------------*/
  2. /* filename -       tgroup.cpp                                */
  3. /*                                                            */
  4. /* function(s)                                                */
  5. /*                  TGroup 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_TGroup
  19. #define Uses_TView
  20. #define Uses_TRect
  21. #define Uses_TEvent
  22. #define Uses_opstream
  23. #define Uses_ipstream
  24. #define Uses_TVMemMgr
  25. #include <tv.h>
  26.  
  27. TView *TheTopView = 0;
  28.  
  29. TGroup::TGroup( const TRect& bounds ) :
  30.     TView(bounds), last( 0 ), phase( phFocused ), current( 0 ), buffer( 0 ),
  31.     lockFlag( 0 ), endState( 0 )
  32. {
  33.     options |= ofSelectable | ofBuffered;
  34.     clip = getExtent();
  35.     eventMask = 0xFFFF;
  36. }
  37.  
  38. TGroup::~TGroup()
  39. {
  40. }
  41.  
  42. void TGroup::shutDown()
  43. {
  44.     TView* p = last;
  45.     if( p != 0 )
  46.         do  {
  47.             TView* T = p->prev();
  48.             destroy( p );
  49.             p = T;
  50.         } while( last != 0 );
  51.     freeBuffer();
  52.     current = 0;
  53.     TView::shutDown();
  54. }
  55.  
  56. void doCalcChange( TView *p, void *d )
  57. {
  58.     TRect  r;
  59.     ((TGroup *)p)->calcBounds(r, *(TPoint*)d);
  60.     ((TGroup *)p)->changeBounds(r);
  61. }
  62.  
  63. void TGroup::changeBounds( const TRect& bounds )
  64. {
  65.     TPoint d;
  66.  
  67.     d.x = (bounds.b.x - bounds.a.x) - size.x;
  68.     d.y = (bounds.b.y - bounds.a.y) - size.y;
  69.     if( d.x == 0 && d.y == 0 )
  70.         {
  71.         setBounds(bounds);
  72.         drawView();
  73.         }
  74.     else
  75.         {
  76.         freeBuffer();
  77.         setBounds( bounds );
  78.         clip = getExtent();
  79.         getBuffer();
  80.         lock();
  81.         forEach( doCalcChange, &d );
  82.         unlock();
  83.         }
  84. }
  85.  
  86. void addSubviewDataSize( TView *p, void *T )
  87. {
  88.    *((ushort *)T) += ((TGroup *)p)->dataSize();
  89. }
  90.  
  91. ushort TGroup::dataSize()
  92. {
  93.     ushort T = 0;
  94.     forEach( addSubviewDataSize, &T );
  95.     return T;
  96. }
  97.  
  98. void TGroup::remove(TView* p)
  99. {
  100.     ushort saveState;
  101.     saveState = p->state;
  102.     p->hide();
  103.     removeView(p);
  104.     p->owner = 0;
  105.     p->next= 0;
  106.     if( (saveState & sfVisible) != 0 )
  107.         p->show();
  108. }
  109.  
  110. void TGroup::draw()
  111. {
  112.     if( buffer == 0 )
  113.         {
  114.         getBuffer();
  115.         if( buffer != 0 )
  116.             {
  117.             lockFlag++;
  118.             redraw();
  119.             lockFlag--;
  120.             }
  121.         }
  122.     if( buffer != 0 )
  123.         writeBuf( 0, 0, size.x, size.y, buffer );
  124.     else
  125.         {
  126.         clip = getClipRect();
  127.         redraw();
  128.         clip = getExtent();
  129.         }
  130. }
  131.  
  132. void TGroup::drawSubViews( TView* p, TView* bottom )
  133. {
  134.     while( p != bottom )
  135.         {
  136.         p->drawView();
  137.         p = p->nextView();
  138.         }
  139. }
  140.  
  141. void TGroup::endModal( ushort command )
  142. {
  143.     if( (state & sfModal) != 0 )
  144.         endState = command;
  145.     else
  146.         TView::endModal( command );
  147. }
  148.  
  149. void TGroup::eventError( TEvent& event )
  150. {
  151.     if (owner != 0 )
  152.         owner->eventError( event );
  153. }
  154.  
  155. ushort TGroup::execute()
  156. {
  157.     do  {
  158.         endState = 0;
  159.         do  {
  160.             TEvent e;
  161.             getEvent( e );
  162.             handleEvent( e );
  163.             if( e.what != evNothing )
  164.                 eventError( e );
  165.             } while( endState == 0 );
  166.     } while( !valid(endState) );
  167.     return endState;
  168. }
  169.  
  170. ushort TGroup::execView( TView* p )
  171. {
  172.     if( p == 0 )
  173.         return cmCancel;
  174.  
  175.     ushort saveOptions = p->options;
  176.     TGroup *saveOwner = p->owner;
  177.     TView *saveTopView = TheTopView;
  178.     TView *saveCurrent= current;
  179.     TCommandSet saveCommands;
  180.     getCommands( saveCommands );
  181.     TheTopView = p;
  182.     p->options = p->options & ~ofSelectable;
  183.     p->setState(sfModal, True);
  184.     setCurrent(p, enterSelect);
  185.     if( saveOwner == 0 )
  186.         insert(p);
  187.     ushort retval = p->execute();
  188.     if( saveOwner == 0 )
  189.         remove(p);
  190.     setCurrent(saveCurrent, leaveSelect);
  191.     p->setState(sfModal, False);
  192.     p->options = saveOptions;
  193.     TheTopView = saveTopView;
  194.     setCommands(saveCommands);
  195.     return retval;
  196. }
  197.  
  198. TView *TGroup::first()
  199. {
  200.     if( last == 0 )
  201.         return 0;
  202.     else
  203.         return last->next;
  204. }
  205.  
  206. TView *TGroup::firstMatch( ushort aState, ushort aOptions )
  207. {
  208.     if( last == 0 )
  209.         return 0;
  210.  
  211.     TView* temp = last;
  212.     while(1)
  213.         {
  214.         if( ((temp->state & aState) == aState) && 
  215.             ((temp->options & aOptions) ==  aOptions))
  216.             return temp;
  217.  
  218.         temp = temp->next;
  219.         if( temp == last )
  220.             return 0;
  221.         }
  222. }
  223.  
  224. void TGroup::freeBuffer()
  225. {
  226.     if( (options & ofBuffered) != 0 && buffer != 0 )
  227.         {
  228.         TVMemMgr::freeDiscardable( buffer );
  229.         buffer = 0;
  230.         }
  231. }
  232.  
  233. void TGroup::getBuffer()
  234. {
  235.     if( (state & sfExposed) != 0 )
  236.         if( (options & ofBuffered) != 0 && (buffer == 0 ))
  237.             TVMemMgr::allocateDiscardable( (void *)buffer, size.x * size.y * sizeof(ushort) );
  238. }
  239.  
  240. void TGroup::getData(void *rec)
  241. {
  242.     ushort i = 0;
  243.     if (last != 0 )
  244.         {
  245.         TView* v = last;
  246.         do  {
  247.             v->getData( ((char *)rec) + i );
  248.             i += v->dataSize();
  249.             v = v->prev();
  250.             } while( v != last );
  251.         }
  252. }
  253.  
  254. struct handleStruct
  255. {
  256.     handleStruct( TEvent& e, TGroup& g ) : event( e ), grp( g ) {}
  257.     TEvent& event;
  258.     TGroup& grp;
  259. };
  260.  
  261. static void doHandleEvent( TView *p, void *s )
  262. {
  263.     handleStruct *ptr = (handleStruct *)s;
  264.  
  265.     if( p == 0 ||
  266.         ( (p->state & sfDisabled) != 0 &&
  267.           (ptr->event.what & (positionalEvents | focusedEvents)) != 0
  268.         )
  269.       )
  270.         return;
  271.  
  272.     switch( ptr->grp.phase )
  273.         {
  274.         case TView::phPreProcess:
  275.             if( (p->options & ofPreProcess) == 0 )
  276.                 return;
  277.             break;
  278.         case TView::phPostProcess:
  279.             if( (p->options & ofPostProcess) == 0 )
  280.                 return;
  281.             break;
  282.         }
  283.     if( (ptr->event.what & p->eventMask) != 0 )
  284.         p->handleEvent( ptr->event );
  285. }
  286.  
  287. static Boolean hasMouse( TView *p, void *s )
  288. {
  289.     return p->containsMouse( *(TEvent *)s );
  290. }
  291.  
  292. void TGroup::handleEvent( TEvent& event )
  293. {
  294.     TView::handleEvent( event );
  295.  
  296.     handleStruct hs( event, *this );
  297.     
  298.     if( (event.what & focusedEvents) != 0 )
  299.         {
  300.         phase = phPreProcess;
  301.         forEach( doHandleEvent, &hs );
  302.  
  303.         phase = phFocused;
  304.         doHandleEvent( current, &hs );
  305.  
  306.         phase = phPostProcess;
  307.         forEach( doHandleEvent, &hs );
  308.         }
  309.     else
  310.         {
  311.         phase = phFocused;
  312.         if( (event.what & positionalEvents) != 0 )
  313.             {
  314.             doHandleEvent( firstThat( hasMouse, &event ), &hs );
  315.             }
  316.         else
  317.             forEach( doHandleEvent, &hs );
  318.         }
  319. }
  320.  
  321. void TGroup::insert( TView* p )
  322. {
  323.     insertBefore( p, first() );
  324. }
  325.  
  326. void TGroup::insertBefore( TView *p, TView *Target )
  327. {
  328.     if( p != 0 && p->owner == 0 && (Target == 0 || Target->owner == this) )
  329.         {
  330.         if( (p->options & ofCenterX) != 0 )
  331.             p->origin.x = (size.x - p->size.x)/2;
  332.         if( (p->options & ofCenterY) != 0 )
  333.             p->origin.y = (size.y - p->size.y)/2;
  334.         ushort saveState = p->state;
  335.         p->hide();
  336.         insertView( p, Target );
  337.         if( (saveState & sfVisible) != 0 )
  338.             p->show();
  339.         }
  340. }
  341.  
  342. void TGroup::insertView( TView* p, TView* Target )
  343. {
  344.     p->owner = this;
  345.     if( Target != 0 )
  346.         {
  347.         Target = Target->prev();
  348.         p->next = Target->next;
  349.         Target->next= p;
  350.         }
  351.     else
  352.         {
  353.         if( last== 0 )
  354.             p->next = p;
  355.         else
  356.             {
  357.             p->next = last->next;
  358.             last->next = p;
  359.             }
  360.         last = p;
  361.         }
  362. }
  363.  
  364. void TGroup::lock()
  365. {
  366.     if( buffer != 0 || lockFlag != 0 )
  367.         lockFlag++;
  368. }
  369.  
  370. void TGroup::redraw()
  371. {
  372.     drawSubViews( first(), 0 );
  373. }
  374.  
  375. void TGroup::resetCurrent()
  376. {
  377.     setCurrent( firstMatch( sfVisible, ofSelectable ), normalSelect );
  378. }
  379.  
  380. void TGroup::resetCursor()
  381. {
  382.     if( current != 0 )
  383.         current->resetCursor();
  384. }
  385.  
  386. void TGroup::selectNext( Boolean forwards )
  387. {
  388.     if( current != 0 )
  389.         {
  390.         TView* p = current;
  391.         do  {
  392.             if (forwards)
  393.                 p = p->next;
  394.             else
  395.                 p = p->prev();
  396.             } while ( !(
  397.               (((p->state & (sfVisible + sfDisabled)) == sfVisible) &&
  398.               (p->options & ofSelectable)) || (p == current)
  399.               ) );
  400.         p->select();
  401.         }
  402. }
  403.  
  404. void TGroup::selectView( TView* p, Boolean enable )
  405. {
  406.     if( p != 0 )
  407.         p->setState( sfSelected, enable );
  408. }
  409.  
  410. void TGroup::focusView( TView* p, Boolean enable )
  411. {
  412.     if( (state & sfFocused) != 0 && p != 0 )
  413.         p->setState( sfFocused, enable );
  414. }
  415.  
  416.  
  417.  
  418. void TGroup::setCurrent( TView* p, selectMode mode )
  419. {
  420.     if (current!= p)
  421.         {
  422.         lock();
  423.         focusView( current, False );
  424.         if( mode != enterSelect )
  425.             if( current != 0 )
  426.                 current->setState( sfSelected, False );
  427.         if( mode != leaveSelect )
  428.             if( p != 0 )
  429.                 p->setState( sfSelected, True );
  430.         if( (state & sfFocused) != 0 && p != 0 )
  431.             p->setState( sfFocused, True );
  432.         current = p;
  433.         unlock();
  434.         }
  435. }
  436.  
  437. void TGroup::setData(void *rec)
  438. {
  439.     ushort i = 0;
  440.     if( last!= 0 )
  441.         {
  442.         TView* v = last;
  443.         do  {
  444.             v->setData( (char *)rec + i );
  445.             i += v->dataSize();
  446.             v = v->prev();
  447.             } while (v != last);
  448.         }
  449. }
  450.  
  451. static void doExpose( TView *p, void *enable )
  452. {
  453.     if( (p->state & sfVisible) != 0 )
  454.         p->setState( sfExposed, *(Boolean *)enable );
  455. }
  456.  
  457. struct setBlock
  458. {
  459.     ushort st;
  460.     Boolean en;
  461. };
  462.  
  463. static void doSetState( TView *p, void *b )
  464. {
  465.     p->setState( ((setBlock *)b)->st, ((setBlock *)b)->en );
  466. }
  467.  
  468. void TGroup::setState( ushort aState, Boolean enable )
  469. {
  470.     setBlock sb;
  471.     sb.st = aState;
  472.     sb.en = enable;
  473.  
  474.     TView::setState( aState, enable );
  475.  
  476.     if( (aState & (sfActive | sfDragging)) != 0 )
  477.         { 
  478.         lock();
  479.         forEach( doSetState, &sb );
  480.         unlock();
  481.         }
  482.  
  483.     if( (aState & sfFocused) != 0 )
  484.         {
  485.         if( current != 0 )
  486.             current->setState( sfFocused, enable );
  487.         }
  488.  
  489.     if( (aState & sfExposed) != 0 )
  490.         {
  491.         forEach( doExpose, &enable );
  492.         if( enable == False )
  493.             freeBuffer();
  494.         }
  495. }
  496.  
  497. void TGroup::unlock()
  498. {
  499.     if( lockFlag != 0 && --lockFlag == 0 )
  500.         drawView();
  501. }
  502.  
  503. static ushort cmd;
  504.  
  505. Boolean isInvalid( TView *p, void * )
  506. {
  507.     return Boolean( !p->valid( cmd ) );
  508. }
  509.  
  510. Boolean TGroup::valid( ushort command )
  511. {
  512.     cmd = command;
  513.     return Boolean( firstThat( isInvalid, 0 ) == 0 );
  514. }
  515.  
  516. ushort TGroup::getHelpCtx()
  517. {
  518.     ushort h = hcNoContext;
  519.     if( current!= 0 )
  520.         h = current->getHelpCtx();
  521.     if (h == hcNoContext)
  522.         h = TView::getHelpCtx();
  523.     return h;
  524. }
  525.  
  526. static void doPut( TView *p, void *osp )
  527. {
  528.     *(opstream *)osp << p;
  529. }
  530.  
  531. void TGroup::write( opstream& os )
  532. {
  533.     ushort index;
  534.  
  535.     TView::write( os );
  536.     TGroup *ownerSave = owner;
  537.     owner = this;
  538.     int count = indexOf( last );
  539.     os << count;
  540.     forEach( doPut, &os );
  541.     if (current == 0)
  542.        index = 0;
  543.     else
  544.        index = indexOf(current);
  545.     os << index;
  546.     owner = ownerSave;
  547. }
  548.  
  549. void *TGroup::read( ipstream& is )
  550. {
  551.     ushort index;
  552.  
  553.     TView::read( is );
  554.     clip = getExtent(); 
  555.     TGroup *ownerSave = owner;
  556.     owner = this;
  557.     last = 0;
  558.     phase = TView::phFocused;
  559.     current = 0;
  560.     buffer = 0;
  561.     lockFlag = 0;
  562.     endState = 0;
  563.     int count;
  564.     is >> count;
  565.     TView *tv;
  566.     for( int i = 0; i < count; i++ )
  567.         {
  568.         is >> tv;
  569.         if( tv != 0 )
  570.             insertView( tv, 0 );
  571.         }
  572.     owner = ownerSave;
  573.     TView *current;
  574.     is >> index;
  575.     current = at(index);
  576.     setCurrent( current, TView::normalSelect );
  577.     return this;
  578. }
  579.  
  580. TStreamable *TGroup::build()
  581. {
  582.     return new TGroup( streamableInit );
  583. }
  584.  
  585. TGroup::TGroup( StreamableInit ) : TView( streamableInit )
  586. {
  587. }
  588.  
  589.  
  590.