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.
This commit is contained in:
ehouse 2007-01-06 17:32:08 +00:00
parent c645534b83
commit bce76a3d34
5 changed files with 133 additions and 62 deletions

View file

@ -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

View file

@ -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 ); */

View file

@ -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 );

View file

@ -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

View file

@ -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 );
}