home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / MotifApp / Extras / TicTacToe / GameBoard.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  7.6 KB  |  287 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //////////////////////////////////////////////////////////////////////////////
  3. //         This example code is from the book:
  4. //
  5. //           Object-Oriented Programming with C++ and OSF/Motif
  6. //         by
  7. //           Douglas Young
  8. //           Prentice Hall, 1992
  9. //           ISBN 0-13-630252-1    
  10. //
  11. //         Copyright 1991 by Prentice Hall
  12. //         All Rights Reserved
  13. //
  14. //  Permission to use, copy, modify, and distribute this software for 
  15. //  any purpose except publication and without fee is hereby granted, provided 
  16. //  that the above copyright notice appear in all copies of the software.
  17. ///////////////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////////////
  19.  
  20.  
  21. ////////////////////////////////////////////////////////////
  22. // GameBoard.C: A tic-tac-toe board
  23. /////////////////////////////////////////////////////////////
  24. #include "TicTacToe.h"
  25. #include "GameBoard.h"
  26. #include "Engine.h"
  27. #include <Xm/RowColumn.h>
  28. #include <Xm/DrawnB.h>
  29.  
  30. GameBoard::GameBoard ( Widget     parent, 
  31.               TicTacToe *game, 
  32.               char      *name ) : UIComponent ( name )
  33. {
  34.     int       i;
  35.     XGCValues values;
  36.     
  37.     _game     = game;    
  38.     _gridSize = 100;
  39.     
  40.     // Create an XmRowColumn widget to manage a 3 X 3 
  41.     // grid of widgets
  42.     
  43.     _w = XtVaCreateWidget ( name, xmRowColumnWidgetClass, parent, 
  44.                XmNnumColumns, 3,
  45.                XmNpacking,    XmPACK_COLUMN,
  46.                XmNadjustLast, FALSE,
  47.                NULL );
  48.     installDestroyHandler();
  49.     
  50.     // Create a grid of 9 XmDrawnButton widgets.
  51.     // Store the index of the widget's position in the grid
  52.     // so it can be used to identify the widget's position later.
  53.     
  54.     for ( i = 0; i < 9; i++ )
  55.     {
  56.     _grid[i] = XtVaCreateWidget ( "xo", 
  57.                      xmDrawnButtonWidgetClass, _w, 
  58.                      XmNuserData,          i,
  59.                      XmNrecomputeSize,     FALSE,
  60.                      XmNpushButtonEnabled, TRUE,
  61.                      XmNshadowType,        XmSHADOW_OUT,
  62.                      XmNwidth,             _gridSize,
  63.                      XmNheight,            _gridSize,
  64.                      NULL );
  65.     
  66.     // Get user input to mark a square
  67.     
  68.     XtAddCallback ( _grid[i], 
  69.                XmNactivateCallback, 
  70.                &GameBoard::markCallback, 
  71.                (XtPointer) this );
  72.     }
  73.     
  74.     XtManageChildren ( _grid, 9 );
  75.     
  76.     // Get the background color of the rowcolumn widget,
  77.     // to be used to effectively shut off highlight-on-enter
  78.     
  79.     XtVaGetValues ( _w, XmNbackground, &_noHighlightColor, NULL );
  80.     
  81.     // Get the GC needed to display the X's and O's
  82.     // and retrieve and save the normal highlight color.
  83.     // Use the color of the first widget in the grid
  84.     
  85.     XtVaGetValues ( _grid[0], XmNforeground,     &values.foreground,
  86.            XmNhighlightColor,  &_highlightColor,
  87.            XmNshadowThickness, &_shadowThickness,
  88.            NULL );
  89.     
  90.     _gc = XtGetGC ( _grid[0], GCForeground, &values );
  91. }
  92.  
  93. GameBoard::~GameBoard()
  94. {
  95.     if ( _w != NULL )
  96.     XtReleaseGC ( _w, _gc );
  97. }
  98.  
  99. void GameBoard::widgetDestroyed()
  100. {
  101.     if ( _w != NULL )
  102.     XtReleaseGC ( _w, _gc );
  103.     _w  = NULL;
  104. }
  105.  
  106. void GameBoard::markX ( int position )
  107. {
  108.     // Remove any previous callbacks, add one to draw 
  109.     // an X and then trigger an Expose event to
  110.     // display the X in this square
  111.     
  112.     XtRemoveAllCallbacks ( _grid[position], XmNexposeCallback );
  113.     
  114.     deactivateSquare ( position ); 
  115.     
  116.     XtAddCallback ( _grid[position], 
  117.            XmNexposeCallback, 
  118.            &GameBoard::drawXCallback, 
  119.            (XtPointer) this );
  120.     
  121.     if ( XtIsRealized ( _grid[position] ) )
  122.     XClearArea ( XtDisplay ( _grid[position] ), 
  123.             XtWindow ( _grid[position] ), 
  124.             0, 0, 0, 0, TRUE );
  125. }
  126.  
  127. void GameBoard::markO ( int position )
  128. {
  129.     // Remove any previous callbacks, add one to draw
  130.     // an O and then trigger an Expose event to
  131.     // display the O in this square
  132.     
  133.     XtRemoveAllCallbacks ( _grid[position], XmNexposeCallback );
  134.     
  135.     deactivateSquare ( position ); 
  136.     
  137.     XtAddCallback ( _grid[position], 
  138.            XmNexposeCallback, 
  139.            &GameBoard::drawOCallback, 
  140.            (XtPointer) this );    
  141.     
  142.     if ( XtIsRealized ( _grid[position] ) )
  143.     XClearArea ( XtDisplay ( _grid[position] ), 
  144.             XtWindow ( _grid[position] ), 
  145.             0, 0, 0, 0, TRUE );
  146. }
  147.  
  148. void GameBoard::drawXCallback ( Widget    w, 
  149.                    XtPointer clientData, 
  150.                    XtPointer )
  151. {
  152.     // Retrieve the GameBoard object
  153.     
  154.     GameBoard *obj = (GameBoard *) clientData;
  155.     
  156.     obj->drawX ( w );
  157. }
  158.  
  159. void GameBoard::drawOCallback ( Widget    w, 
  160.                    XtPointer clientData, 
  161.                    XtPointer )
  162. {
  163.     GameBoard *obj = (GameBoard *) clientData;
  164.     
  165.     obj->drawO ( w );
  166. }
  167.  
  168. void GameBoard::drawX ( Widget square )
  169. {
  170.     // Draw the X across the widget
  171.     
  172.     int left   = (int) ( 0.2 * _gridSize );
  173.     int top    = (int) ( 0.2 * _gridSize );
  174.     int right  = (int) ( 0.8 * _gridSize );
  175.     int bottom = (int) ( 0.8 * _gridSize );
  176.     
  177.     XDrawLine ( XtDisplay ( square ), 
  178.            XtWindow ( square ), 
  179.            _gc, 
  180.            left, top, right, bottom );
  181.     XDrawLine ( XtDisplay ( square ), 
  182.            XtWindow ( square ), 
  183.            _gc, 
  184.            right, top, left, bottom );
  185. }
  186.  
  187. void GameBoard::drawO ( Widget square )
  188. {
  189.     // Draw a circle that occupies 80% of the widget
  190.     
  191.     int left   = (int) ( 0.2 * _gridSize );
  192.     int top    = (int) ( 0.2 * _gridSize );
  193.     int width  = (int) ( 0.6 * _gridSize );
  194.     int height = (int) ( 0.6 * _gridSize );
  195.     
  196.     XDrawArc ( XtDisplay ( square ), 
  197.           XtWindow ( square ),
  198.           _gc, 
  199.           left, top, width, height, 0, 360 * 64 );
  200. }
  201.  
  202. void GameBoard::clear()
  203. {
  204.     int i;
  205.     
  206.     // Each element of the grid may have a callback for an X 
  207.     // or an O, so all callbacks must be removed.
  208.     
  209.     for ( i = 0; i < 9; i++ ) 
  210.     {
  211.     XtRemoveAllCallbacks ( _grid[i], XmNexposeCallback );    
  212.     
  213.     activateSquare ( i );
  214.     
  215.     // Use XClearArea, with exposure events requested
  216.     // so that the widget's shadow is redrawn
  217.     
  218.     if ( XtIsRealized ( _grid[i] ) )
  219.         XClearArea ( XtDisplay ( _grid[i] ), 
  220.             XtWindow ( _grid[i] ),
  221.             0, 0, 0, 0, TRUE );
  222.     }
  223. }
  224.  
  225. void GameBoard::markCallback ( Widget    w, 
  226.                   XtPointer clientData, 
  227.                   XtPointer )
  228. {
  229.     GameBoard *obj = (GameBoard *) clientData;
  230.     int index;
  231.     
  232.     XtVaGetValues ( w, XmNuserData, &index, NULL );
  233.     
  234.     obj->mark ( index );
  235. }
  236.  
  237. void GameBoard::mark ( int index )
  238. {
  239.     _game->engine()->recordMove ( index );
  240. }
  241.  
  242. void GameBoard::activateSquare ( int position )
  243. {
  244.     // Make the button look active by setting the shadow
  245.     // type to normal, enabling pushbutton behavior, and
  246.     // turning on highlights when the mouse enters the square
  247.     
  248.     XtVaSetValues( _grid[position],  
  249.           XmNpushButtonEnabled, TRUE,
  250.           XmNshadowType,        XmSHADOW_OUT,
  251.           XmNshadowThickness,   _shadowThickness,
  252.           XmNhighlightColor,    _highlightColor,
  253.           NULL );
  254. }
  255.  
  256. void GameBoard::deactivateSquare ( int position )
  257. {
  258.     // Change a button to appear inactive by setting the shadow
  259.     // type so the button is depressed, disabling pushbutton 
  260.     // behavior, and turning off the highlight-on-enter feature
  261.     
  262.     XtVaSetValues ( _grid[position],
  263.            XmNpushButtonEnabled, FALSE,
  264.            XmNshadowType,        XmSHADOW_IN,
  265.            XmNhighlightColor,   _noHighlightColor,
  266.            NULL );
  267.     
  268. }
  269.  
  270. void GameBoard::highlightSquare ( int position )
  271. {
  272.     // Emphasize a square by changing the shadow type
  273.     
  274.     XtVaSetValues ( _grid[position],
  275.            XmNshadowType,      XmSHADOW_ETCHED_OUT,
  276.            XmNshadowThickness, 2 * _shadowThickness,
  277.            NULL );
  278. }
  279.  
  280. void GameBoard::deemphasizeSquare ( int position )
  281. {
  282.     // Make a square fade into the background by shutting
  283.     // the Motif three-D effect
  284.     
  285.     XtVaSetValues ( _grid[position], XmNshadowThickness, 0, NULL );
  286. }
  287.