diff --git a/xwords4/common/board.c b/xwords4/common/board.c index e365ea6c3..5e8642df3 100644 --- a/xwords4/common/board.c +++ b/xwords4/common/board.c @@ -1456,6 +1456,60 @@ board_invalRect( BoardCtxt* board, XP_Rect* rect ) } } /* board_invalRect */ +#ifdef XWFEATURE_ACTIVERECT +XP_Bool +board_getActiveRect( const BoardCtxt* board, XP_Rect* rect ) +{ + XP_Bool found = XP_FALSE; + XP_USE( rect ); + XP_U16 minCol = 1000; + XP_U16 maxCol = 0; + XP_U16 minRow = 1000; + XP_U16 maxRow = 0; + const ModelCtxt* model = board->model; + XP_U16 nCols = model_numCols( board->model ); + XP_S16 turn = board->selPlayer; + XP_U16 col, row; + + for ( col = 0; col < nCols; ++col ) { + for ( row = 0; row < nCols; ++row ) { + if ( model_getTile( model, col, row, XP_TRUE, turn, NULL, NULL, + NULL, NULL ) ) { + found = XP_TRUE; + if ( row < minRow ) { + minRow = row; + } + if ( row > maxRow ) { + maxRow = row; + } + if ( col < minCol ) { + minCol = col; + } + if ( col > maxCol ) { + maxCol = col; + } + } + } + } + + if ( !found ) { + minCol = maxCol = nCols / 2; + minRow = maxRow = nCols / 2; + found = XP_TRUE; + } + + XP_Rect upperLeft, lowerRight; + getCellRect( board, minCol, minRow, &upperLeft ); + getCellRect( board, maxCol, maxRow, &lowerRight ); + rect->left = upperLeft.left; + rect->top = upperLeft.top; + rect->width = (lowerRight.left + lowerRight.width) - upperLeft.left; + rect->height = (lowerRight.top + lowerRight.height) - upperLeft.top; + + return found; +} +#endif + /* When the tray's hidden, check if it overlaps where the board wants to be, * and adjust the board's rect if needed so that hit-testing will work * "through" where the tray used to be. diff --git a/xwords4/common/board.h b/xwords4/common/board.h index 10de9e0a1..82591369c 100644 --- a/xwords4/common/board.h +++ b/xwords4/common/board.h @@ -96,6 +96,9 @@ void board_setTimerLoc( BoardCtxt* board, XP_U16 timerWidth, XP_U16 timerHeight ); void board_invalAll( BoardCtxt* board ); void board_invalRect( BoardCtxt* board, XP_Rect* rect ); +#ifdef XWFEATURE_ACTIVERECT +XP_Bool board_getActiveRect( const BoardCtxt* board, XP_Rect* rect ); +#endif XP_Bool board_draw( BoardCtxt* board ); @@ -119,6 +122,7 @@ BoardObjectType board_getFocusOwner( BoardCtxt* board ); void board_hiliteCellAt( BoardCtxt* board, XP_U16 col, XP_U16 row ); + void board_resetEngine( BoardCtxt* board ); XP_Bool board_commitTurn( BoardCtxt* board ); diff --git a/xwords4/linux/Makefile b/xwords4/linux/Makefile index 74f954b65..89a838acd 100644 --- a/xwords4/linux/Makefile +++ b/xwords4/linux/Makefile @@ -113,6 +113,7 @@ DEFINES += -DXWFEATURE_HILITECELL DEFINES += -DXWFEATURE_CHANGEDICT DEFINES += -DXWFEATURE_DEVID DEFINES += -DXWFEATURE_COMMSACK +#DEFINES += -DXWFEATURE_ACTIVERECT DEFINES += -DCOMMS_XPORT_FLAGSPROC DEFINES += -DINITIAL_CLIENT_VERS=2 diff --git a/xwords4/linux/gtkboard.c b/xwords4/linux/gtkboard.c index 257449cd8..e180f228d 100644 --- a/xwords4/linux/gtkboard.c +++ b/xwords4/linux/gtkboard.c @@ -1071,6 +1071,28 @@ handle_memstats( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals ) } /* handle_memstats */ #endif +#ifdef XWFEATURE_ACTIVERECT +static gint +inval_board_ontimer( gpointer data ) +{ + GtkGameGlobals* globals = (GtkGameGlobals*)data; + BoardCtxt* board = globals->cGlobals.game.board; + board_draw( board ); + return XP_FALSE; +} /* pen_timer_func */ + +static void +frame_active( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals ) +{ + XP_Rect rect; + BoardCtxt* board = globals->cGlobals.game.board; + board_getActiveRect( board, &rect ); + frame_active_rect( globals->draw, &rect ); + board_invalRect( board, &rect ); + (void)g_timeout_add( 1000, inval_board_ontimer, globals ); +} +#endif + static GtkWidget* createAddItem( GtkWidget* parent, gchar* label, GtkSignalFunc handlerFunc, GtkGameGlobals* globals ) @@ -1157,6 +1179,11 @@ makeMenus( GtkGameGlobals* globals ) GTK_SIGNAL_FUNC(handle_memstats), globals ); #endif +#ifdef XWFEATURE_ACTIVERECT + fileMenu = makeAddSubmenu( menubar, "Test" ); + (void)createAddItem( fileMenu, "Frame active area", + GTK_SIGNAL_FUNC(frame_active), globals ); +#endif /* (void)createAddItem( fileMenu, "Print board", */ /* GTK_SIGNAL_FUNC(handle_print_board), globals ); */ diff --git a/xwords4/linux/gtkdraw.c b/xwords4/linux/gtkdraw.c index dd350f42c..2d1942b49 100644 --- a/xwords4/linux/gtkdraw.c +++ b/xwords4/linux/gtkdraw.c @@ -1299,9 +1299,9 @@ allocAndSet( GdkColormap* map, GdkColor* color, unsigned short red, gboolean success = #endif gdk_colormap_alloc_color( map, - color, - TRUE, /* writeable */ - TRUE ); /* best-match */ + color, + TRUE, /* writeable */ + TRUE ); /* best-match */ XP_ASSERT( success ); } /* allocAndSet */ @@ -1440,5 +1440,11 @@ draw_gtk_status( GtkDrawCtx* dctx, char ch ) &dctx->black, NULL ); } +void +frame_active_rect( GtkDrawCtx* dctx, const XP_Rect* rect ) +{ + gtkFillRect( dctx, rect, &dctx->grey ); +} + #endif /* PLATFORM_GTK */ diff --git a/xwords4/linux/gtkdraw.h b/xwords4/linux/gtkdraw.h index 452575a3c..0545474dc 100644 --- a/xwords4/linux/gtkdraw.h +++ b/xwords4/linux/gtkdraw.h @@ -25,5 +25,6 @@ DrawCtx* gtkDrawCtxtMake( GtkWidget *widget, GtkGameGlobals* globals ); void draw_gtk_status( GtkDrawCtx* draw, char ch ); +void frame_active_rect( GtkDrawCtx* dctx, const XP_Rect* rect ); #endif