home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tv20os2.zip / src / TGroup.cpp < prev    next >
C/C++ Source or Header  |  1998-07-21  |  13KB  |  655 lines

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