From bce76a3d34b657167dd47ef6e8949b0f443eb2d1 Mon Sep 17 00:00:00 2001 From: ehouse Date: Sat, 6 Jan 2007 17:32:08 +0000 Subject: [PATCH] Break key handling into keyUp and keyDown, and treat keyDown the same as penDown. Idea is to be able to set timers to get bonus square hints etc. without stylus. Works, but transitions are rough because keyDown doesn't know whether keyUp will result in a focus change. --- common/board.c | 169 ++++++++++++++++++++++++++++++++-------------- common/board.h | 5 +- common/boardp.h | 2 + common/scorebdp.c | 3 + common/tray.c | 16 ++--- 5 files changed, 133 insertions(+), 62 deletions(-) diff --git a/common/board.c b/common/board.c index ceadbd173..8a10cbeea 100644 --- a/common/board.c +++ b/common/board.c @@ -2201,6 +2201,41 @@ checkRevealTray( BoardCtxt* board ) return result; } /* checkRevealTray */ +static XP_Bool +handleLikeDown( BoardCtxt* board, BoardObjectType onWhich, XP_U16 x, XP_U16 y ) +{ + XP_Bool result = XP_FALSE; + + switch ( onWhich ) { + case OBJ_BOARD: + result = handlePenDownOnBoard( board, x, y ) || result; + break; + + case OBJ_TRAY: + XP_ASSERT( board->trayVisState != TRAY_HIDDEN ); + + if ( board->trayVisState != TRAY_REVERSED ) { + result = handlePenDownInTray( board, x, y ) || result; + } + break; + + case OBJ_SCORE: + if ( figureScorePlayerTapped( board, x, y ) >= 0 ) { + util_setTimer( board->util, TIMER_PENDOWN, 0, + p_board_timerFired, board ); + } + break; + default: + break; + } + + board->penDownX = x; + board->penDownY = y; + board->penDownObject = onWhich; + + return result; +} /* handleLikeDown */ + #ifdef POINTER_SUPPORT XP_Bool board_handlePenDown( BoardCtxt* board, XP_U16 x, XP_U16 y, XP_Bool* handled ) @@ -2222,37 +2257,8 @@ board_handlePenDown( BoardCtxt* board, XP_U16 x, XP_U16 y, XP_Bool* handled ) board->focusHasDived = XP_FALSE; #endif - switch ( onWhich ) { - - case OBJ_BOARD: - result = handlePenDownOnBoard( board, x, y ) || result; - break; - - case OBJ_TRAY: - /* XP_ASSERT( board->trayIsVisible ); */ - XP_ASSERT( board->trayVisState != TRAY_HIDDEN ); - - if ( board->trayVisState != TRAY_REVERSED ) { - result = handlePenDownInTray( board, x, y ) || result; - } - break; - - case OBJ_SCORE: - if ( figureScorePlayerTapped( board, x, y ) >= 0 ) { - util_setTimer( board->util, TIMER_PENDOWN, 0, - p_board_timerFired, board ); - } - break; - default: - break; - } - - board->penDownX = x; - board->penDownY = y; - board->penDownObject = onWhich; - /* board->inDrag = XP_TRUE; */ + result = handleLikeDown( board, onWhich, x, y ); } - *handled = penDidSomething; return result; /* no redraw needed */ @@ -2524,8 +2530,82 @@ flipKey( XP_Key key, XP_Bool flip ) { } /* flipKey */ #endif +static void +getRectCenter( const XP_Rect* rect, XP_U16* xp, XP_U16* yp ) +{ + *xp = rect->left + ( rect->width >> 1 ); + *yp = rect->top + ( rect->height >> 1 ); +} + +static void +getFocussedCellCenter( BoardCtxt* board, XP_U16* xp, XP_U16* yp ) +{ + XP_Rect rect; + XP_U16 selPlayer = board->selPlayer; + BdCursorLoc* cursorLoc = &board->bdCursor[selPlayer]; + + getCellRect( board, cursorLoc->col, cursorLoc->row, &rect ); + getRectCenter( &rect, xp, yp ); +} + +static void +getFocussedTileCenter( BoardCtxt* board, XP_U16* xp, XP_U16* yp ) +{ + XP_Rect rect; + XP_U16 indx = board->trayCursorLoc[board->selPlayer]; + figureTrayTileRect( board, indx, &rect ); + getRectCenter( &rect, xp, yp ); +} + +static void +getFocussedScoreCenter( BoardCtxt* board, XP_U16* xp, XP_U16* yp ) +{ + getRectCenter( &board->scoreRects[board->scoreCursorLoc], xp, yp ); +} + +static XP_Bool +focusToCoords( BoardCtxt* board, XP_U16* xp, XP_U16* yp ) +{ + XP_Bool result = board->focusHasDived; + if ( result ) { + switch( board->focussed ) { + case OBJ_NONE: + result = XP_FALSE; + break; + case OBJ_BOARD: + getFocussedCellCenter( board, xp, yp ); + break; + case OBJ_TRAY: + getFocussedTileCenter( board, xp, yp ); + break; + case OBJ_SCORE: + getFocussedScoreCenter( board, xp, yp ); + break; + } + } + + return result; +} + XP_Bool -board_handleKey( BoardCtxt* board, XP_Key key, XP_Bool* pHandled ) +board_handleKeyDown( BoardCtxt* board, XP_Key key, XP_Bool* pHandled ) +{ + XP_Bool draw = XP_FALSE; + XP_U16 x, y; + + if ( key == XP_RETURN_KEY ) { + if ( focusToCoords( board, &x, &y ) ) { + draw = handleLikeDown( board, board->focussed, x, y ); + } + } + + *pHandled = (board->focussed != OBJ_NONE) && board->focusHasDived; + + return draw; +} + +XP_Bool +board_handleKeyUp( BoardCtxt* board, XP_Key key, XP_Bool* pHandled ) { XP_Bool redraw = XP_FALSE; XP_Bool handled = XP_FALSE; @@ -2585,26 +2665,11 @@ board_handleKey( BoardCtxt* board, XP_Key key, XP_Bool* pHandled ) case XP_RETURN_KEY: if ( board->focusHasDived ) { - handled = XP_TRUE; /* even if don't draw, we handle it!! */ - if ( board->focussed == OBJ_TRAY ) { - if ( trayVisible ) { - redraw = tray_keyAction( board ); - } else { - redraw = askRevealTray( board ); - } - } else if ( board->focussed == OBJ_BOARD ) { - /* mimic pen-down/pen-up on cursor */ - if ( trayVisible ) { - BdCursorLoc loc = board->bdCursor[board->selPlayer]; - redraw = handleActionInCell( board, loc.col, loc.row ); - } else { - redraw = askRevealTray( board ); - } - } else if ( board->focussed == OBJ_SCORE ) { - /* tap on what's already selected: reveal tray, etc. */ - board_selectPlayer( board, board->scoreCursorLoc ); - redraw = XP_TRUE; /* must assume */ - } + XP_U16 x, y; + if ( focusToCoords( board, &x, &y ) ) { + redraw = board_handlePenUp( board, x, y ); + handled = XP_TRUE; + } } else if ( board->focussed != OBJ_NONE ) { redraw = invalFocusOwner( board ); board->focusHasDived = XP_TRUE; @@ -2629,7 +2694,7 @@ board_handleKey( BoardCtxt* board, XP_Key key, XP_Bool* pHandled ) *pHandled = handled; } return redraw; -} /* board_handleKey */ +} /* board_handleKeyUp */ #ifdef KEYBOARD_NAV diff --git a/common/board.h b/common/board.h index 3ee5cae7a..3ca66b779 100644 --- a/common/board.h +++ b/common/board.h @@ -35,7 +35,7 @@ extern "C" { typedef enum { /* keep these three together: for the cursor */ - XP_KEY_NONE, + XP_KEY_NONE = 0, XP_CURSOR_KEY_DOWN, XP_CURSOR_KEY_ALTDOWN, @@ -126,7 +126,8 @@ XP_Bool board_handlePenMove( BoardCtxt* board, XP_U16 x, XP_U16 y ); XP_Bool board_handlePenUp( BoardCtxt* board, XP_U16 x, XP_U16 y ); #endif -XP_Bool board_handleKey( BoardCtxt* board, XP_Key key, XP_Bool* handled ); +XP_Bool board_handleKeyUp( BoardCtxt* board, XP_Key key, XP_Bool* handled ); +XP_Bool board_handleKeyDown( BoardCtxt* board, XP_Key key, XP_Bool* handled ); #ifdef KEYBOARD_NAV /* void board_focusChange( BoardCtxt* board ); */ diff --git a/common/boardp.h b/common/boardp.h index fc1ce49dc..f34800b15 100644 --- a/common/boardp.h +++ b/common/boardp.h @@ -124,6 +124,7 @@ struct BoardCtxt { BoardArrow boardArrow[MAX_NUM_PLAYERS]; #ifdef KEYBOARD_NAV + XP_Rect scoreRects[MAX_NUM_PLAYERS]; BdCursorLoc bdCursor[MAX_NUM_PLAYERS]; XP_Bool focusHasDived; #endif @@ -193,6 +194,7 @@ XP_U16 indexForBits( XP_U8 bits ); XP_Bool rectContainsPt( XP_Rect* rect1, XP_S16 x, XP_S16 y ); XP_Bool checkRevealTray( BoardCtxt* board ); void invalTilesUnderRect( BoardCtxt* board, XP_Rect* rect ); +void figureTrayTileRect( BoardCtxt* board, XP_U16 index, XP_Rect* rect ); XP_Bool rectsIntersect( const XP_Rect* rect1, const XP_Rect* rect2 ); void board_selectPlayer( BoardCtxt* board, XP_U16 newPlayer ); diff --git a/common/scorebdp.c b/common/scorebdp.c index a4ef22289..05221283e 100644 --- a/common/scorebdp.c +++ b/common/scorebdp.c @@ -169,6 +169,9 @@ drawScoreBoard( BoardCtxt* board ) innerRect.top = scoreRect.top + ((scoreRect.height - innerRect.height) / 2); + XP_MEMCPY( &board->scoreRects[i], &scoreRect, + sizeof(scoreRect) ); + draw_score_drawPlayer( board->draw, &innerRect, &scoreRect, &dp->dsi ); #ifdef KEYBOARD_NAV diff --git a/common/tray.c b/common/tray.c index 0aeaea7a6..f7040c367 100644 --- a/common/tray.c +++ b/common/tray.c @@ -85,7 +85,7 @@ pointToTileIndex( BoardCtxt* board, XP_U16 x, XP_U16 y, XP_Bool* onDividerP ) return result; } /* pointToTileIndex */ -static void +void figureTrayTileRect( BoardCtxt* board, XP_U16 index, XP_Rect* rect ) { rect->left = board->trayBounds.left + (index * board->trayScaleH); @@ -673,13 +673,13 @@ tray_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool* pUp ) /* Revisit this when able to never draw the cursor in a place this won't allow it, e.g. when the tiles move after a hint */ -/* if ( board->trayVisState == TRAY_REVEALED ) { */ -/* XP_U16 count = model_getNumTilesInTray( board->model, */ -/* selPlayer ); */ -/* if ( (pos > count) && (pos < MAX_TRAY_TILES-1) ) { */ -/* continue; */ -/* } */ -/* } */ + if ( board->trayVisState == TRAY_REVEALED ) { + XP_U16 count = model_getNumTilesInTray( board->model, + selPlayer ); + if ( (pos > count) && (pos < MAX_TRAY_TILES-1) ) { + continue; + } + } board->trayCursorLoc[selPlayer] = pos; board_invalTrayTiles( board, 1 << pos ); }