mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
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:
parent
c645534b83
commit
bce76a3d34
5 changed files with 133 additions and 62 deletions
169
common/board.c
169
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
|
||||
|
||||
|
|
|
@ -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 ); */
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue