home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK4 / SAMPLES / CPPTUTOR / OOD / INTERACT.CP$ / INTERACT
Encoding:
Text File  |  1991-11-06  |  12.7 KB  |  519 lines

  1. /********************************************************************
  2.  
  3.  FILE: INTERACT.CPP
  4.  
  5. ********************************************************************/
  6.  
  7. #include "interact.h"
  8.  
  9. #include <stdio.h>
  10. #include <conio.h>
  11. #include <ctype.h>
  12. #include <dos.h>
  13. #include <string.h>
  14.  
  15. /********************************************************************
  16.  
  17.  Buffer::Buffer
  18.  
  19. ********************************************************************/
  20.  
  21. Buffer::Buffer( int wid, int len, unsigned char defAttr )
  22. {
  23.     int i, j;
  24.  
  25.     width = wid;
  26.     length = len;
  27.     textArray = new ScreenChar[wid * len];
  28.     defaultAttr = defAttr;
  29.  
  30.     for( i = 0; i < width; i++ )
  31.        for( j = 0; j < length; j++ )
  32.            setChar( Point( i, j ), ' ', defaultAttr );
  33. }
  34.  
  35.  
  36. /********************************************************************
  37.  
  38.  Buffer::Buffer - copy constructor
  39.  
  40. ********************************************************************/
  41.  
  42. Buffer::Buffer( const Buffer &other )
  43. {
  44.     int i, j;
  45.     ScreenChar temp;
  46.  
  47.     width = other.width;
  48.     length = other.length;
  49.     textArray = new ScreenChar[ width * length ];
  50.     for( i = 0; i < width; i++ )
  51.         for( j = 0; j < length; j++ )
  52.         {
  53.             temp = other.getChar( Point( i, j ) );
  54.             setChar( Point( i, j ), temp.character, temp.attribute );
  55.         }
  56.     defaultAttr = other.defaultAttr;
  57. }
  58.  
  59. /********************************************************************
  60.  
  61.  Buffer::operator=
  62.  
  63.  This function assigns one buffer to another.
  64.  
  65. ********************************************************************/
  66.  
  67. Buffer &Buffer::operator=( const Buffer &other )
  68. {
  69.     int i, j;
  70.     ScreenChar temp;
  71.  
  72.     if( &other == this)   // check for self-assignment
  73.         return *this;
  74.  
  75.     width = other.width;
  76.     length = other.length;
  77.     delete textArray;
  78.     textArray = new ScreenChar[ width * length ];
  79.     for( i = 0; i < width; i++ )
  80.         for( j = 0; j < length; j++ )
  81.         {
  82.             temp = other.getChar( Point( i, j ) );
  83.             setChar( Point( i, j ), temp.character, temp.attribute );
  84.         }
  85.     defaultAttr = other.defaultAttr;
  86.     return *this;
  87. }
  88.  
  89. /********************************************************************
  90.  
  91.  Buffer::setChar
  92.  
  93.  This function sets the character at the specified location. If no
  94.  attribute is specified, the default attribute of the buffer is used.
  95.  
  96. ********************************************************************/
  97.  
  98. void Buffer::setChar( Point loc, char newChar, unsigned char newAttr )
  99. {
  100.    if( newAttr == 0 )
  101.       newAttr = defaultAttr;
  102.  
  103.    textArray[(loc.y * width) + loc.x].character = newChar;
  104.    textArray[(loc.y * width) + loc.x].attribute = newAttr;
  105. }
  106.  
  107. /********************************************************************
  108.  
  109.  Buffer::getChar
  110.  
  111.  This function returns the ScreenChar found at the specified location.
  112.  
  113. ********************************************************************/
  114.  
  115. ScreenChar Buffer::getChar( Point loc ) const
  116. {
  117.    ScreenChar temp;
  118.  
  119.    temp.character = textArray[(loc.y * width) + loc.x].character;
  120.    temp.attribute = textArray[(loc.y * width) + loc.x].attribute;
  121.  
  122.    return temp;
  123. }
  124.  
  125. /********************************************************************
  126.  
  127.  Buffer::putStr
  128.  
  129.  This function writes a string at the specified location. If no
  130.  attribute was specified, the default attribute of the buffer is
  131.  used. Text is wrapped at the end of each line.
  132.  
  133. ********************************************************************/
  134.  
  135. void Buffer::putStr( Point loc, char *newStr, unsigned char newAttr )
  136. {
  137.     int i = 0;
  138.  
  139.     if( newAttr == 0 )
  140.        newAttr = defaultAttr;
  141.  
  142.     while( newStr[i] != '\0' )
  143.     {
  144.        setChar( loc, newStr[i], newAttr );
  145.        loc.x++;
  146.        if( loc.x == width )
  147.        {
  148.            loc.x = 0;
  149.           loc.y++;
  150.        }
  151.        if( loc.y == length )
  152.           return;
  153.  
  154.        i++;
  155.     }
  156. }
  157.  
  158. /********************************************************************
  159.  
  160.  Buffer::~Buffer
  161.  
  162. ********************************************************************/
  163.  
  164. Buffer::~Buffer()
  165. {
  166.    delete textArray;
  167. }
  168.  
  169. /********************************************************************
  170.  
  171.  Win::setTitle
  172.  
  173.  This function sets the title of a window.
  174.  
  175. ********************************************************************/
  176.  
  177. int Win::setTitle( char *newstr )
  178. {
  179.    if( title )
  180.        delete title;
  181.  
  182.    title = new char[strlen( newstr ) + 1];
  183.  
  184.    strcpy( title, newstr );
  185.  
  186.    return 1;
  187. }
  188.  
  189. /********************************************************************
  190.  
  191.  Win::paintFrame
  192.  
  193.  This function paints the frame around a top-level window. A
  194.  double-lined frame is painted if the window is active, and a single-
  195.  lined frame is painted if the window is inactive. If a title exists,
  196.  it is written over the frame.
  197.  
  198. ********************************************************************/
  199.  
  200. void Win::paintFrame() const
  201. {
  202.    int i;
  203.    char upLeft,
  204.         upRight,
  205.         botLeft,
  206.         botRight,
  207.         vert,
  208.         horiz;
  209.    unsigned char attr = WHITE_FORE | BLACK_BACK;
  210.  
  211.    if( active )
  212.    {
  213.       upLeft   = (char)201;
  214.       botLeft  = (char)200;
  215.       upRight  = (char)187;
  216.       botRight = (char)188;
  217.       vert     = (char)186;
  218.       horiz    = (char)205;
  219.    }
  220.    else
  221.    {
  222.       upLeft   = (char)218;
  223.       botLeft  = (char)192;
  224.       upRight  = (char)191;
  225.       botRight = (char)217;
  226.       vert     = (char)179;
  227.       horiz    = (char)196;
  228.    }
  229.  
  230.    paintChar( Point( 0, 0 ), upLeft, attr );
  231.    paintChar( Point( 0, height() - 1 ), botLeft, attr );
  232.    paintChar( Point( width() - 1, 0 ), upRight, attr );
  233.    paintChar( Point( width() - 1, height() - 1 ), botRight, attr );
  234.  
  235.    for( i = 1; i < height() - 1; i++ )
  236.    {
  237.       paintChar( Point( 0, i ), vert, attr );
  238.       paintChar( Point( width() - 1, i ), vert, attr );
  239.    }
  240.  
  241.    for( i = 1; i < width() - 1; i++ )
  242.    {
  243.       paintChar( Point( i, 0 ), horiz, attr );
  244.       paintChar( Point( i, height() - 1 ), horiz, attr );
  245.    }
  246.  
  247.  
  248.    if( *title )
  249.    {
  250.       i = 0;
  251.       while( (i < width() - 2) &&
  252.              (title[i] != '\0')  )
  253.       {
  254.      paintChar( Point(2 + i, 0), title[i], attr);
  255.      i++;
  256.       }
  257.    }
  258. }
  259.  
  260. /********************************************************************
  261.  
  262.  ScrollBar::ScrollBar
  263.  
  264.  This function constructs a scroll bar, given a parent window, the
  265.  location of the scroll bar on the window, the length of the scroll
  266.  bar, and its orientation (horizontal or vertical).
  267.  
  268. ********************************************************************/
  269.  
  270. ScrollBar::ScrollBar( Win *parent, Point location, int len, int orient )
  271. : Control( parent )
  272. {
  273.    if( orient == VERT )
  274.    {
  275.       area = Rect( location.x,
  276.                    location.y,
  277.                    location.x,
  278.                    location.y + len - 1 );
  279.    }
  280.    else  // orient == HORIZ
  281.    {
  282.       area = Rect( location.x,
  283.                    location.y,
  284.                    location.x + len - 1,
  285.                    location.y );
  286.    }
  287.  
  288.    length = len;
  289.    sliderPos = 1;
  290.    orientation = orient;
  291.    active = 1;
  292. }
  293.  
  294.  
  295. /********************************************************************
  296.  
  297.  ScrollBar::resize
  298.  
  299.  This function resizes a scroll bar. Depending on the orientation
  300.  of the scroll bar, one of the parameters is ignored, since scroll
  301.  bars are restricted to being one character in thickness.
  302.  
  303. ********************************************************************/
  304.  
  305. void ScrollBar::resize( int newWidth, int newLength )
  306. {
  307.    if( orientation == VERT )
  308.    {
  309.       length = newLength;
  310.       Interactor::resize( 1, newLength );
  311.    }
  312.    else  // orientation == HORIZ
  313.    {
  314.       length = newWidth;
  315.       Interactor::resize( newWidth, 1 );
  316.    }
  317.  
  318. }
  319.  
  320.  
  321. /********************************************************************
  322.  
  323.  ScrollBar::handleEvent
  324.  
  325.  This function handles mouse events; scroll bars do not respond to
  326.  any other kind of events. The function creates ScrollEvent objects
  327.  and sends them to the parent window.
  328.  
  329. ********************************************************************/
  330.  
  331. void ScrollBar::handleEvent( const Event &action )
  332. {
  333.    switch ( action.getType() )
  334.    {
  335.    case MOUSE_EVENT:
  336.  
  337.       int eventpos;
  338.  
  339.       if( orientation == VERT )
  340.          eventpos = ( (MouseEvent &) action).getPosition().y;
  341.  
  342.       else  // orientation == HORIZ
  343.          eventpos = ( (MouseEvent &) action).getPosition().x;
  344.  
  345.       if( eventpos == 0 )
  346.          parentWin->handleEvent( ScrollEvent( BACKWARD, LINE, this ) );
  347.  
  348.       else if( eventpos == length - 1 )
  349.          parentWin->handleEvent( ScrollEvent( FORWARD, LINE, this ) );
  350.  
  351.       else if( eventpos < sliderPos )
  352.          parentWin->handleEvent( ScrollEvent( BACKWARD, PAGE, this ) );
  353.  
  354.       else if( eventpos > sliderPos )
  355.          parentWin->handleEvent( ScrollEvent( FORWARD, PAGE, this ) );
  356.  
  357.       break;
  358.  
  359.    default:
  360.       break;
  361.    }
  362. }
  363.  
  364.  
  365. /********************************************************************
  366.  
  367.  ScrollBar::paint
  368.  
  369.  This function paints the scrollbar. First the painting region is
  370.  set to the rectangle specified for updating (paintingRegion is used
  371.  by paintChar). The body of the scroll bar is painted, and if the
  372.  scroll bar is active, the arrows and slider are painted.
  373.  
  374. ********************************************************************/
  375.  
  376. void ScrollBar::paint( Rect region )
  377. {
  378.    int i;
  379.    unsigned char at = BLUE_FORE | GREEN_BACK;
  380.  
  381.  
  382.     paintingRegion = region;
  383.  
  384.     // whether active or inactive, paint body of scroll bar
  385.  
  386.     if( orientation == VERT )
  387.         for( i = 0; i <= length - 1; i++ )
  388.             paintChar( Point( 0, i ), (char)178, at);
  389.  
  390.     else
  391.         for( i = 0; i <= length - 1; i++ )
  392.             paintChar( Point( i, 0 ), (char)178, at);
  393.  
  394.     if( active )   // now paint slider and end arrows
  395.     {
  396.         if( orientation == VERT )
  397.         {
  398.             paintChar( Point( 0, 0 ), (char)30, at );
  399.             paintChar( Point( 0, length - 1 ), (char)31, at );
  400.             paintChar( Point( 0, sliderPos ), (char)254, at );
  401.         }
  402.         else   // orientation == HORIZ
  403.         {
  404.             paintChar( Point( 0, 0 ), (char)17, at );
  405.             paintChar( Point( length - 1, 0 ), (char)16, at );
  406.             paintChar( Point( sliderPos, 0 ), (char)254, at );
  407.         }
  408.     }
  409. }
  410.  
  411.  
  412. /********************************************************************
  413.  
  414.  ScrollBar::setSlider
  415.  
  416.  This function sets the slider position. The specified position
  417.  must be a number between 1 and 100, inclusive.
  418.  
  419. ********************************************************************/
  420.  
  421. int ScrollBar::setSlider( int pos )
  422. {
  423.    int slideSpan;
  424.  
  425.    pos = max( pos, 1 );
  426.    pos = min( pos, 100 );
  427.  
  428.    slideSpan = length - 2;
  429.  
  430.    sliderPos = 1 + ((pos * (slideSpan - 1)) / 100) ;
  431.    return 1;
  432. }
  433.  
  434.  
  435. /********************************************************************
  436.  
  437.  PushButton::PushButton
  438.  
  439.  This function constructs a push button, given a parent window,
  440.  the location of the button on the window, and a label for the
  441.  button.
  442.  
  443. ********************************************************************/
  444.  
  445. PushButton::PushButton( Win *parent, Point location, char *labl )
  446. : Control( parent )
  447. {
  448.    area = Rect( location.x, location.y,
  449.                 location.x + strlen( labl ) - 1, location.y );
  450.    pressed = FALSE;
  451.    strcpy( label, labl );
  452.    active = 1;
  453. }
  454.  
  455.  
  456. /********************************************************************
  457.  
  458.  PushButton::handleEvent
  459.  
  460.  This function handles mouse events; push buttons do not respond to
  461.  any other kind of event. The button is painted with colors inverted,
  462.  a delay loop is executed, and then the button is painted again with
  463.  normal colors.
  464.  
  465. ********************************************************************/
  466.  
  467. void PushButton::handleEvent( const Event &action )
  468. {
  469.    switch ( action.getType() )
  470.    {
  471.    case MOUSE_EVENT:
  472.  
  473.       pressed = TRUE;
  474.       paint( Rect( 0, 0, width(), height() ) );
  475.  
  476. //      delay(100);
  477.  
  478.       pressed = FALSE;
  479.       paint( Rect( 0, 0, width(), height() ) );
  480.       parentWin->handleEvent( PushEvent( this ) );
  481.       break;
  482.  
  483.    default:
  484.       break;
  485.    }
  486. }
  487.  
  488. /********************************************************************
  489.  
  490.  PushButton::paint
  491.  
  492.  This function paints a button. If a button is pressed, it is painted
  493.  with inverted colors.
  494.  
  495. ********************************************************************/
  496.  
  497. void PushButton::paint( Rect region )
  498. {
  499.    unsigned int i = 0;
  500.    unsigned char attr;
  501.  
  502.    paintingRegion = region;
  503.  
  504.    if( active )
  505.    {
  506.        if( pressed )
  507.            attr = WHITE_FORE | BLACK_BACK;
  508.        else
  509.            attr = BLACK_FORE | WHITE_BACK;
  510.    }
  511.    else // inactive
  512.        attr = GRAY_FORE | WHITE_BACK;
  513.  
  514.    for( i = 0; i < strlen( label ); i++ )
  515.        paintChar( Point(i,0), label[i], attr );
  516. }
  517.  
  518.  
  519.