home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // This example code is from the book:
- //
- // Object-Oriented Programming with C++ and OSF/Motif
- // by
- // Douglas Young
- // Prentice Hall, 1992
- // ISBN 0-13-630252-1
- //
- // Copyright 1991 by Prentice Hall
- // All Rights Reserved
- //
- // Permission to use, copy, modify, and distribute this software for
- // any purpose except publication and without fee is hereby granted, provided
- // that the above copyright notice appear in all copies of the software.
- ///////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
-
-
- ////////////////////////////////////////////////////////////
- // GameBoard.C: A tic-tac-toe board
- /////////////////////////////////////////////////////////////
- #include "TicTacToe.h"
- #include "GameBoard.h"
- #include "Engine.h"
- #include <Xm/RowColumn.h>
- #include <Xm/DrawnB.h>
-
- GameBoard::GameBoard ( Widget parent,
- TicTacToe *game,
- char *name ) : UIComponent ( name )
- {
- int i;
- XGCValues values;
-
- _game = game;
- _gridSize = 100;
-
- // Create an XmRowColumn widget to manage a 3 X 3
- // grid of widgets
-
- _w = XtVaCreateWidget ( name, xmRowColumnWidgetClass, parent,
- XmNnumColumns, 3,
- XmNpacking, XmPACK_COLUMN,
- XmNadjustLast, FALSE,
- NULL );
- installDestroyHandler();
-
- // Create a grid of 9 XmDrawnButton widgets.
- // Store the index of the widget's position in the grid
- // so it can be used to identify the widget's position later.
-
- for ( i = 0; i < 9; i++ )
- {
- _grid[i] = XtVaCreateWidget ( "xo",
- xmDrawnButtonWidgetClass, _w,
- XmNuserData, i,
- XmNrecomputeSize, FALSE,
- XmNpushButtonEnabled, TRUE,
- XmNshadowType, XmSHADOW_OUT,
- XmNwidth, _gridSize,
- XmNheight, _gridSize,
- NULL );
-
- // Get user input to mark a square
-
- XtAddCallback ( _grid[i],
- XmNactivateCallback,
- &GameBoard::markCallback,
- (XtPointer) this );
- }
-
- XtManageChildren ( _grid, 9 );
-
- // Get the background color of the rowcolumn widget,
- // to be used to effectively shut off highlight-on-enter
-
- XtVaGetValues ( _w, XmNbackground, &_noHighlightColor, NULL );
-
- // Get the GC needed to display the X's and O's
- // and retrieve and save the normal highlight color.
- // Use the color of the first widget in the grid
-
- XtVaGetValues ( _grid[0], XmNforeground, &values.foreground,
- XmNhighlightColor, &_highlightColor,
- XmNshadowThickness, &_shadowThickness,
- NULL );
-
- _gc = XtGetGC ( _grid[0], GCForeground, &values );
- }
-
- GameBoard::~GameBoard()
- {
- if ( _w != NULL )
- XtReleaseGC ( _w, _gc );
- }
-
- void GameBoard::widgetDestroyed()
- {
- if ( _w != NULL )
- XtReleaseGC ( _w, _gc );
- _w = NULL;
- }
-
- void GameBoard::markX ( int position )
- {
- // Remove any previous callbacks, add one to draw
- // an X and then trigger an Expose event to
- // display the X in this square
-
- XtRemoveAllCallbacks ( _grid[position], XmNexposeCallback );
-
- deactivateSquare ( position );
-
- XtAddCallback ( _grid[position],
- XmNexposeCallback,
- &GameBoard::drawXCallback,
- (XtPointer) this );
-
- if ( XtIsRealized ( _grid[position] ) )
- XClearArea ( XtDisplay ( _grid[position] ),
- XtWindow ( _grid[position] ),
- 0, 0, 0, 0, TRUE );
- }
-
- void GameBoard::markO ( int position )
- {
- // Remove any previous callbacks, add one to draw
- // an O and then trigger an Expose event to
- // display the O in this square
-
- XtRemoveAllCallbacks ( _grid[position], XmNexposeCallback );
-
- deactivateSquare ( position );
-
- XtAddCallback ( _grid[position],
- XmNexposeCallback,
- &GameBoard::drawOCallback,
- (XtPointer) this );
-
- if ( XtIsRealized ( _grid[position] ) )
- XClearArea ( XtDisplay ( _grid[position] ),
- XtWindow ( _grid[position] ),
- 0, 0, 0, 0, TRUE );
- }
-
- void GameBoard::drawXCallback ( Widget w,
- XtPointer clientData,
- XtPointer )
- {
- // Retrieve the GameBoard object
-
- GameBoard *obj = (GameBoard *) clientData;
-
- obj->drawX ( w );
- }
-
- void GameBoard::drawOCallback ( Widget w,
- XtPointer clientData,
- XtPointer )
- {
- GameBoard *obj = (GameBoard *) clientData;
-
- obj->drawO ( w );
- }
-
- void GameBoard::drawX ( Widget square )
- {
- // Draw the X across the widget
-
- int left = (int) ( 0.2 * _gridSize );
- int top = (int) ( 0.2 * _gridSize );
- int right = (int) ( 0.8 * _gridSize );
- int bottom = (int) ( 0.8 * _gridSize );
-
- XDrawLine ( XtDisplay ( square ),
- XtWindow ( square ),
- _gc,
- left, top, right, bottom );
- XDrawLine ( XtDisplay ( square ),
- XtWindow ( square ),
- _gc,
- right, top, left, bottom );
- }
-
- void GameBoard::drawO ( Widget square )
- {
- // Draw a circle that occupies 80% of the widget
-
- int left = (int) ( 0.2 * _gridSize );
- int top = (int) ( 0.2 * _gridSize );
- int width = (int) ( 0.6 * _gridSize );
- int height = (int) ( 0.6 * _gridSize );
-
- XDrawArc ( XtDisplay ( square ),
- XtWindow ( square ),
- _gc,
- left, top, width, height, 0, 360 * 64 );
- }
-
- void GameBoard::clear()
- {
- int i;
-
- // Each element of the grid may have a callback for an X
- // or an O, so all callbacks must be removed.
-
- for ( i = 0; i < 9; i++ )
- {
- XtRemoveAllCallbacks ( _grid[i], XmNexposeCallback );
-
- activateSquare ( i );
-
- // Use XClearArea, with exposure events requested
- // so that the widget's shadow is redrawn
-
- if ( XtIsRealized ( _grid[i] ) )
- XClearArea ( XtDisplay ( _grid[i] ),
- XtWindow ( _grid[i] ),
- 0, 0, 0, 0, TRUE );
- }
- }
-
- void GameBoard::markCallback ( Widget w,
- XtPointer clientData,
- XtPointer )
- {
- GameBoard *obj = (GameBoard *) clientData;
- int index;
-
- XtVaGetValues ( w, XmNuserData, &index, NULL );
-
- obj->mark ( index );
- }
-
- void GameBoard::mark ( int index )
- {
- _game->engine()->recordMove ( index );
- }
-
- void GameBoard::activateSquare ( int position )
- {
- // Make the button look active by setting the shadow
- // type to normal, enabling pushbutton behavior, and
- // turning on highlights when the mouse enters the square
-
- XtVaSetValues( _grid[position],
- XmNpushButtonEnabled, TRUE,
- XmNshadowType, XmSHADOW_OUT,
- XmNshadowThickness, _shadowThickness,
- XmNhighlightColor, _highlightColor,
- NULL );
- }
-
- void GameBoard::deactivateSquare ( int position )
- {
- // Change a button to appear inactive by setting the shadow
- // type so the button is depressed, disabling pushbutton
- // behavior, and turning off the highlight-on-enter feature
-
- XtVaSetValues ( _grid[position],
- XmNpushButtonEnabled, FALSE,
- XmNshadowType, XmSHADOW_IN,
- XmNhighlightColor, _noHighlightColor,
- NULL );
-
- }
-
- void GameBoard::highlightSquare ( int position )
- {
- // Emphasize a square by changing the shadow type
-
- XtVaSetValues ( _grid[position],
- XmNshadowType, XmSHADOW_ETCHED_OUT,
- XmNshadowThickness, 2 * _shadowThickness,
- NULL );
- }
-
- void GameBoard::deemphasizeSquare ( int position )
- {
- // Make a square fade into the background by shutting
- // the Motif three-D effect
-
- XtVaSetValues ( _grid[position], XmNshadowThickness, 0, NULL );
- }
-