home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / tvision / wrdwrp / tview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-19  |  18.6 KB  |  790 lines

  1. #pragma warn -stv
  2. /*------------------------------------------------------------*/
  3. /* filename -       tview.cpp                                 */
  4. /*                                                            */
  5. /* function(s)                                                */
  6. /*                  TView member functions                    */
  7. /*------------------------------------------------------------*/
  8.  
  9. /*------------------------------------------------------------*/
  10. /*                                                            */
  11. /*    Turbo Vision -  Version 1.0                             */
  12. /*                                                            */
  13. /*                                                            */
  14. /*    Copyright (c) 1991 by Borland International             */
  15. /*    All Rights Reserved.                                    */
  16. /*                                                            */
  17. /*------------------------------------------------------------*/
  18.  
  19. //  Primatech Modification History:
  20. //
  21. //      11-25-91 JLS  Changed change() to have the shift state passed in
  22. //      12-19-91 JLS  Added STACKCHECK() (only effects #ifdef DEBUG)
  23. //
  24.  
  25. #define Uses_TKeys
  26. #define Uses_TView
  27. #define Uses_TCommandSet
  28. #define Uses_TPoint
  29. #define Uses_TGroup
  30. #define Uses_TRect
  31. #define Uses_TEvent
  32. #define Uses_opstream
  33. #define Uses_ipstream
  34. #include <tv.h>
  35.  
  36. #if !defined( __DOS_H )
  37. #include <Dos.h>
  38. #endif  // __DOS_H
  39.  
  40. #if !defined( __LIMITS_H )
  41. #include <Limits.h>
  42. #endif  // __LIMITS_H
  43.  
  44. #include "StackChk.h"
  45.  
  46. TPoint shadowSize = {2,1};
  47. uchar shadowAttr = 0x08;
  48. Boolean near TView::showMarkers = False;
  49. uchar near TView::errorAttr = 0xCF;
  50. Boolean near TView::commandSetChanged = False;
  51.  
  52. extern TView *TheTopView;
  53.  
  54. static TCommandSet initCommands()
  55. {
  56.     TCommandSet temp;
  57.     for( int i = 0; i < 256; i++ )
  58.         temp.enableCmd( i );
  59.     temp.disableCmd( cmZoom );
  60.     temp.disableCmd( cmClose );
  61.     temp.disableCmd( cmResize );
  62.     temp.disableCmd( cmNext );
  63.     temp.disableCmd( cmPrev );
  64.     return temp;
  65. }
  66.  
  67. TCommandSet near TView::curCommandSet = initCommands();
  68.  
  69. TView::TView( const TRect& bounds) :
  70.     owner( 0 ), next( 0 ), options( 0 ), state( sfVisible ),
  71.     growMode( 0 ), dragMode( dmLimitLoY ), helpCtx( hcNoContext ),
  72.     eventMask( evMouseDown | evKeyDown | evCommand )
  73. {
  74.     setBounds( bounds);
  75.     cursor.x = cursor.y = 0;
  76. }
  77.  
  78. TView::~TView()
  79. {
  80. }
  81.  
  82. void TView::blockCursor()
  83. {
  84.      setState(sfCursorIns, True);
  85. }
  86.  
  87. #define grow(i) (( (growMode & gfGrowRel)) ? \
  88.                 (i = (i * s + ((s - d) >> 1)) / (s - d)) : (i += d))
  89.  
  90. inline int range( int val, int min, int max )
  91. {
  92.     if( val < min )
  93.         return min;
  94.     else if( val > max )
  95.         return max;
  96.     else
  97.         return val;
  98. }
  99.                 
  100. void TView::calcBounds( TRect& bounds, TPoint delta )
  101. {
  102.     bounds = getBounds();
  103.  
  104.     short s = owner->size.x;
  105.     short d = delta.x;
  106.  
  107.     if( (growMode & gfGrowLoX) != 0 )
  108.         grow(bounds.a.x);
  109.  
  110.     if( (growMode & gfGrowHiX) != 0 )
  111.         grow(bounds.b.x);
  112.  
  113.     s = owner->size.y;
  114.     d = delta.y;
  115.  
  116.     if( (growMode & gfGrowLoY) != 0 )
  117.         grow(bounds.a.y);
  118.  
  119.     if( (growMode & gfGrowHiY) != 0 )
  120.         grow(bounds.b.y);
  121.  
  122.     TPoint minLim, maxLim;
  123.     sizeLimits( minLim, maxLim );
  124.     bounds.b.x = bounds.a.x + range( bounds.b.x-bounds.a.x, minLim.x, maxLim.x );
  125.     bounds.b.y = bounds.a.y + range( bounds.b.y-bounds.a.y, minLim.y, maxLim.y );
  126. }
  127.  
  128. void TView::changeBounds( const TRect& bounds )
  129. {
  130.     setBounds(bounds);
  131.     drawView();
  132. }
  133.  
  134. void TView::clearEvent( TEvent& event )
  135. {
  136.     STACKCHECK();
  137.  
  138.     event.what = evNothing;
  139.     event.message.infoPtr = this;
  140. }
  141.  
  142. Boolean TView::commandEnabled( ushort command )
  143. {
  144.     return Boolean((command > 255) || curCommandSet.has(command));
  145. }
  146.  
  147. ushort TView::dataSize()
  148. {
  149.     return 0;
  150. }
  151.  
  152. void TView::disableCommands( TCommandSet& commands )
  153. {
  154.     commandSetChanged = Boolean( commandSetChanged ||
  155.                                 !(curCommandSet & commands).isEmpty());
  156.     curCommandSet.disableCmd(commands);
  157. }
  158.  
  159. void TView::disableCommand( ushort command )
  160. {
  161.     commandSetChanged = Boolean( commandSetChanged ||
  162.                                  curCommandSet.has(command) );
  163.     curCommandSet.disableCmd(command);
  164. }
  165.  
  166. void TView::moveGrow( TPoint p,
  167.                       TPoint s,
  168.                       TRect& limits,
  169.                       TPoint minSize,
  170.                       TPoint maxSize,
  171.                       uchar mode
  172.                     )
  173. {
  174.     TRect   r;
  175.     s.x = min(max(s.x, minSize.x), maxSize.x);
  176.     s.y = min(max(s.y, minSize.y), maxSize.y);
  177.     p.x = min(max(p.x, limits.a.x - s.x+1), limits.b.x-1);
  178.     p.y = min(max(p.y, limits.a.y - s.y+1), limits.b.y-1);
  179.  
  180.     if( (mode & dmLimitLoX) != 0 )
  181.         p.x = max(p.x, limits.a.x);
  182.     if( (mode & dmLimitLoY) != 0 )
  183.         p.y = max(p.y, limits.a.y);
  184.     if( (mode & dmLimitHiX) != 0 )
  185.         p.x = min(p.x, limits.b.x-s.x);
  186.     if( (mode & dmLimitHiY) != 0 )
  187.         p.y = min(p.y, limits.b.y-s.y);
  188.     r = TRect(p.x, p.y, p.x +  s.x, p.y +  s.y);
  189.     locate(r);
  190. }
  191.  
  192. void TView::change( uchar mode, TPoint delta, TPoint& p, TPoint& s, uchar shiftState )
  193. {
  194.     if( (mode & dmDragMove) != 0 && (shiftState & 3) == 0 )
  195.         p += delta;
  196.     else if( (mode & dmDragGrow) != 0 && (shiftState & 3) != 0 )
  197.         s += delta;
  198. }
  199.  
  200. void TView::dragView( TEvent& event,
  201.                       uchar mode,
  202.                       TRect& limits,
  203.                       TPoint minSize,
  204.                       TPoint maxSize
  205.                     )
  206. {
  207.     TRect saveBounds;
  208.  
  209.     TPoint p, s;
  210.     setState( sfDragging, True );
  211.  
  212.     if( event.what == evMouseDown )
  213.         {
  214.         if( (mode & dmDragMove) != 0 )
  215.             {
  216.             p = origin - event.mouse.where;
  217.             do  {
  218.                 event.mouse.where += p;
  219.                 moveGrow( event.mouse.where,
  220.                           size,
  221.                           limits,
  222.                           minSize,
  223.                           maxSize,
  224.                           mode
  225.                         );
  226.                 } while( mouseEvent(event,evMouseMove) );
  227.             }
  228.         else
  229.             {
  230.             p = size - event.mouse.where;
  231.             do  {
  232.                 event.mouse.where += p;
  233.                 moveGrow( origin,
  234.                           event.mouse.where,
  235.                           limits,
  236.                           minSize,
  237.                           maxSize,
  238.                           mode
  239.                         );
  240.                 } while( mouseEvent(event,evMouseMove) );
  241.             }
  242.         }
  243.     else
  244.         {
  245.         static TPoint 
  246.             goLeft      =   {-1, 0}, 
  247.             goRight     =   { 1, 0}, 
  248.             goUp        =   { 0,-1}, 
  249.             goDown      =   { 0, 1}, 
  250.             goCtrlLeft  =   {-8, 0}, 
  251.             goCtrlRight =   { 8, 0};
  252.             
  253.         saveBounds = getBounds();
  254.         do  {
  255.             p = origin;
  256.             s = size;
  257.             keyEvent(event);
  258.             switch (event.keyDown.keyCode & 0xFF00)
  259.                 {
  260.                 case kbLeft:
  261.                     change(mode, goLeft, p, s, event.shiftState);
  262.                     break;
  263.                 case kbRight:
  264.                     change(mode, goRight, p, s, event.shiftState);
  265.                     break;
  266.                 case kbUp:
  267.                     change(mode, goUp, p, s, event.shiftState);
  268.                     break;
  269.                 case kbDown:
  270.                     change(mode, goDown, p, s, event.shiftState);
  271.                     break;
  272.                 case kbCtrlLeft:
  273.                     change(mode, goCtrlLeft, p, s, event.shiftState);
  274.                     break;
  275.                 case kbCtrlRight:
  276.                     change(mode, goCtrlRight, p, s, event.shiftState);
  277.                     break;
  278.                 case kbHome:
  279.                     p.x = limits.a.x;
  280.                     break;
  281.                 case kbEnd:
  282.                     p.x = limits.b.x - s.x;
  283.                     break;
  284.                 case kbPgUp:
  285.                     p.y = limits.a.y;
  286.                     break;
  287.                 case kbPgDn:
  288.                     p.y = limits.b.y - s.y;
  289.                     break;
  290.                 }
  291.             moveGrow( p, s, limits, minSize, maxSize, mode );
  292.             } while( event.keyDown.keyCode != kbEsc &&
  293.                      event.keyDown.keyCode != kbEnter
  294.                    );
  295.         if( event.keyDown.keyCode == kbEsc )
  296.             locate(saveBounds);
  297.         }
  298.     setState(sfDragging, False);
  299. }
  300.  
  301. void TView::draw()
  302. {
  303.     TDrawBuffer  b;
  304.  
  305.     b.moveChar( 0, ' ', getColor(1), size.x );
  306.     writeLine( 0, 0, size.x, size.y, b );
  307.  
  308.     STACKCHECK();
  309. }
  310.  
  311. void TView::drawCursor()
  312. {
  313.     if( (state & sfFocused) != 0 )
  314.         resetCursor();
  315. }
  316.  
  317. void TView::drawHide( TView* lastView )
  318. {
  319.     drawCursor();
  320.     drawUnderView(Boolean(state & sfShadow), lastView);
  321. }
  322.  
  323. void TView::drawShow( TView* lastView )
  324. {
  325.     drawView();
  326.     if( (state & sfShadow) != 0 )
  327.         drawUnderView( True, lastView );
  328. }
  329.  
  330. void TView::drawUnderRect( TRect& r, TView* lastView )
  331. {
  332.     owner->clip.intersect(r);
  333.     owner->drawSubViews(nextView(), lastView);
  334.     owner->clip = owner->getExtent();
  335. }
  336.  
  337. void TView::drawUnderView( Boolean doShadow, TView* lastView )
  338. {
  339.     TRect r = getBounds();
  340.     if( doShadow != False )
  341.         r.b += shadowSize;
  342.     drawUnderRect( r, lastView );
  343. }
  344.  
  345. void TView::drawView()
  346. {
  347.     if (exposed())
  348.         {
  349.         draw();
  350.         drawCursor();
  351.         }
  352. }
  353.  
  354. void TView::enableCommands( TCommandSet& commands )
  355. {
  356.     commandSetChanged = Boolean( commandSetChanged ||
  357.                                 ((curCommandSet&commands) != commands) );
  358.     curCommandSet += commands;
  359. }
  360.  
  361. void TView::enableCommand( ushort command )
  362. {
  363.     commandSetChanged = Boolean( commandSetChanged ||
  364.                                  !curCommandSet.has( command ) );
  365.     curCommandSet += command;
  366. }
  367.  
  368. void TView::endModal( ushort command )
  369. {
  370.     if( TopView() != 0 )
  371.         TopView()->endModal(command);
  372. }
  373.  
  374. Boolean  TView::eventAvail()
  375. {
  376.     TEvent event;
  377.     getEvent(event);
  378.     if( event.what != evNothing )
  379.         putEvent(event);
  380.     return Boolean( event.what != evNothing );
  381. }
  382.  
  383. TRect TView::getBounds()
  384. {
  385.     return TRect( origin, origin+size );
  386. }
  387.  
  388. ushort  TView::execute()
  389. {
  390.     return cmCancel;
  391. }
  392.  
  393. TRect TView::getClipRect()
  394. {
  395.     TRect clip = getBounds();
  396.     if( owner != 0 )
  397.         clip.intersect(owner->clip);
  398.     clip.move(-origin.x, -origin.y);
  399.     return clip;
  400. }
  401.  
  402. ushort TView::getColor( ushort color )
  403. {
  404.     ushort colorPair = color >> 8;
  405.  
  406.     if( colorPair != 0 )
  407.         colorPair = mapColor(colorPair) << 8;
  408.  
  409.     colorPair |= mapColor( uchar(color) );
  410.  
  411.     return colorPair;
  412. }
  413.  
  414. void TView::getCommands( TCommandSet& commands )
  415. {
  416.     commands = curCommandSet;
  417. }
  418.  
  419. void TView::getData( void * )
  420. {
  421. }
  422.  
  423. void TView::getEvent( TEvent& event )
  424. {
  425.     if( owner != 0 )
  426.         owner->getEvent(event);
  427. }
  428.  
  429. TRect TView::getExtent()
  430. {
  431.     return TRect( 0, 0, size.x, size.y );
  432. }
  433.  
  434. ushort TView::getHelpCtx()
  435. {
  436.     if( (state & sfDragging) != 0 )
  437.         return hcDragging;
  438.     return helpCtx;
  439. }
  440.  
  441. TPalette& TView::getPalette() const
  442. {
  443.     static char ch = 0;
  444.     static TPalette palette( &ch, 0 );
  445.     return palette;
  446. }
  447.  
  448. Boolean TView::getState( ushort aState )
  449. {
  450.     return Boolean( (state & aState) == aState );
  451. }
  452.  
  453. void TView::growTo( short x, short y )
  454. {
  455.     TRect r;
  456.     r = TRect(origin.x, origin.y, origin.x + x, origin.y + y);
  457.     locate(r);
  458. }
  459.  
  460. void TView::handleEvent(TEvent& event)
  461. {
  462.     if( event.what == evMouseDown )
  463.         {
  464.         if(!(state & (sfSelected | sfDisabled)) && (options & ofSelectable) )
  465.             {
  466.             select();
  467.             if( !(options & ofFirstClick) )
  468.                 clearEvent(event);
  469.             }
  470.         }
  471.  
  472.     STACKCHECK();
  473. }
  474.  
  475. void TView::hide()
  476. {
  477.     if( (state & sfVisible) != 0 )
  478.         setState( sfVisible, False );
  479. }
  480.  
  481. void TView::hideCursor()
  482. {
  483.     setState( sfCursorVis, False );
  484. }
  485.  
  486. void TView::keyEvent( TEvent& event )
  487. {
  488.     do {
  489.        getEvent(event);
  490.         } while( event.what != evKeyDown );
  491. }
  492.  
  493. #define range(Val, Min, Max)    (((Val < Min) ? Min : ((Val > Max) ? Max : Val)))
  494.  
  495. void TView::locate( TRect& bounds )
  496. {
  497.     TPoint   min, max;
  498.     sizeLimits(min, max);
  499.     bounds.b.x = bounds.a.x + range(bounds.b.x - bounds.a.x, min.x, max.x);
  500.     bounds.b.y = bounds.a.y + range(bounds.b.y - bounds.a.y, min.y, max.y);
  501.     TRect r = getBounds();
  502.     if( bounds != r )
  503.         {
  504.         changeBounds( bounds );
  505.         if( owner != 0 && (state & sfVisible) != 0 )
  506.             {
  507.             if( (state & sfShadow) != 0 )
  508.                 {
  509.                 r.Union(bounds);
  510.                 r.b += shadowSize;
  511.                 }
  512.             drawUnderRect( r, 0 );
  513.             }
  514.         }
  515. }
  516.  
  517. void TView::makeFirst()
  518. {
  519.     putInFrontOf(owner->first());
  520. }
  521.  
  522. TPoint TView::makeGlobal( TPoint source )
  523. {
  524.     TPoint temp = source + origin;
  525.     TView *cur = this;
  526.     while( cur->owner != 0 )
  527.         {
  528.         cur = cur->owner;
  529.         temp += cur->origin;
  530.         }
  531.     return temp;
  532. }
  533.  
  534. TPoint TView::makeLocal( TPoint source )
  535. {
  536.     TPoint temp = source - origin;
  537.     TView* cur = this;
  538.     while( cur->owner != 0 )
  539.         {
  540.         cur = cur->owner;
  541.         temp -= cur->origin;
  542.         }
  543.     return temp;
  544. }
  545.  
  546. Boolean TView::mouseEvent(TEvent& event, ushort mask)
  547. {
  548.     do {
  549.        getEvent(event);
  550.         } while( !(event.what & (mask | evMouseUp)) );
  551.  
  552.     return Boolean(event.what != evMouseUp);
  553. }
  554.  
  555. Boolean TView::mouseInView(TPoint mouse)
  556. {
  557.      mouse = makeLocal( mouse );
  558.      TRect r = getExtent();
  559.      return r.contains(mouse);
  560. }
  561.  
  562. void TView::moveTo( short x, short y )
  563. {
  564.      locate( TRect( x, y, x+size.x, y+size.y ) );
  565. }
  566.  
  567. TView *TView::nextView()
  568. {
  569.     if( this == owner->last )
  570.         return 0;
  571.     else
  572.         return next;
  573. }
  574.  
  575. void TView::normalCursor()
  576. {
  577.     setState(sfCursorIns, False);
  578. }
  579.  
  580. TView *TView::prev()
  581. {
  582.     TView* res = this;
  583.     while( res->next != this )
  584.         res = res->next;
  585.     return res;
  586. }
  587.  
  588. TView *TView::prevView()
  589. {
  590.     if( this == owner->first() )
  591.         return 0;
  592.     else
  593.         return prev();
  594. }
  595.  
  596. void TView::putEvent( TEvent& event )
  597. {
  598.     if( owner != 0 )
  599.         owner->putEvent(event);
  600. }
  601.  
  602. void TView::putInFrontOf( TView *Target )
  603. {
  604.     TView *p, *lastView;
  605.  
  606.     if( owner != 0 && Target != this && Target != nextView() &&
  607.          ( Target == 0 || Target->owner == owner)
  608.       )
  609.         if( (state & sfVisible) == 0 )
  610.             {
  611.             owner->removeView(this);
  612.             owner->insertView(this, Target);
  613.             }
  614.         else
  615.             {
  616.             lastView = nextView();
  617.             p = Target;
  618.             while( p != 0 && p != this )
  619.                 p = p->nextView();
  620.             if( p == 0 )
  621.                 lastView = Target;
  622.             state &= ~sfVisible;
  623.             if( lastView == Target )
  624.                 drawHide(lastView);
  625.             owner->removeView(this);
  626.             owner->insertView(this, Target);
  627.             state |= sfVisible;
  628.             if( lastView != Target )
  629.                 drawShow(lastView);
  630.             if( (options & ofSelectable) != 0 )
  631.                 owner->resetCurrent();
  632.             }
  633. }
  634.  
  635. void TView::select()
  636. {
  637.     if( (options & ofTopSelect) != 0 )
  638.         makeFirst();
  639.     else if( owner != 0 )
  640.         owner->setCurrent( this, normalSelect );
  641.  
  642.     STACKCHECK();
  643. }
  644.  
  645. void TView::setBounds( const TRect& bounds )
  646. {            
  647.     origin = bounds.a;
  648.     size = bounds.b - bounds.a;
  649. }
  650.  
  651. void TView::setCommands( TCommandSet& commands )
  652. {
  653.     commandSetChanged = Boolean( commandSetChanged ||
  654.                                 (curCommandSet != commands ));
  655.     curCommandSet = commands;
  656. }
  657.  
  658. void TView::setCursor( short x, short y )
  659. {
  660.     cursor.x = x;
  661.     cursor.y = y;
  662.     drawCursor();
  663. }
  664.  
  665. void TView::setData( void * )
  666. {
  667. }
  668.  
  669. void TView::setState( ushort aState, Boolean enable )
  670. {
  671.     if( enable == True )
  672.         state |= aState;
  673.     else
  674.         state &= ~aState;
  675.  
  676.     if( owner == 0 )
  677.         return;
  678.  
  679.     switch( aState )
  680.         {
  681.         case  sfVisible:
  682.             if( (owner->state & sfExposed) != 0 )
  683.                 setState( sfExposed, enable );
  684.             if( enable == True )
  685.                 drawShow( 0 );
  686.             else
  687.                 drawHide( 0 );
  688.             if( (options & ofSelectable) != 0 )
  689.                 owner->resetCurrent();
  690.             break;
  691.         case  sfCursorVis:
  692.         case  sfCursorIns:
  693.             drawCursor();
  694.             break;
  695.         case  sfShadow:
  696.             drawUnderView( True, 0 );
  697.             break;
  698.         case  sfFocused:
  699.             resetCursor();
  700.             message( owner,
  701.                      evBroadcast,
  702.                      (enable == True) ? cmReceivedFocus : cmReleasedFocus,
  703.                      this
  704.                    );
  705.             break;
  706.         }
  707. }
  708.  
  709. void TView::show()
  710. {
  711.     if( (state & sfVisible) == 0 )
  712.         setState(sfVisible, True);
  713. }
  714.  
  715. void TView::showCursor()
  716. {
  717.     setState( sfCursorVis, True );
  718. }
  719.  
  720. void TView::sizeLimits( TPoint& min, TPoint& max )
  721. {
  722.     min.x = min.y = 0;
  723.     if( owner != 0 )
  724.         max = owner->size;
  725.     else
  726.         max.x = max.y = INT_MAX;
  727. }
  728.  
  729. TView* TView::TopView()
  730. {
  731.     if( TheTopView != 0 )
  732.         return TheTopView;
  733.     else
  734.         {
  735.         TView* p = this;
  736.         while( p != 0 && !(p->state & sfModal) )
  737.             p = p->owner;
  738.         return p;
  739.         }
  740. }
  741.  
  742. Boolean TView::valid( ushort )
  743. {
  744.     return True;
  745. }
  746.  
  747. Boolean TView::containsMouse( TEvent& event )
  748. {
  749.     return Boolean( (state & sfVisible) != 0 &&
  750.                     mouseInView( event.mouse.where )
  751.                   );
  752. }
  753.  
  754. void TView::shutDown()
  755. {
  756.     hide();
  757.     if( owner != 0 )
  758.         owner->remove( this );
  759.     TObject::shutDown();
  760. }
  761.  
  762. void TView::write( opstream& os )
  763. {
  764.     ushort saveState =
  765.         state & ~( sfActive | sfSelected | sfFocused | sfExposed );
  766.  
  767.     os << origin << size << cursor
  768.        << growMode << dragMode << helpCtx
  769.        << saveState << options << eventMask;
  770. }
  771.  
  772. void *TView::read( ipstream& is )
  773. {
  774.     is >> origin >> size >> cursor
  775.        >> growMode >> dragMode >> helpCtx
  776.        >> state >> options >> eventMask;
  777.     owner = 0;
  778.     next = 0;
  779.     return this;
  780. }
  781.  
  782. TStreamable *TView::build()
  783. {
  784.     return new TView( streamableInit );
  785. }
  786.  
  787. TView::TView( StreamableInit )
  788. {
  789. }
  790.