mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
When scrolling in response to a drag, invalidate under the tile both
before and after the scroll. Otherwise on platforms where scrolling is via a bitmove the old position gets scrolled away and never redrawn leaving ghost tile parts lying around.
This commit is contained in:
parent
ddafe8b97a
commit
ffd7dffd27
3 changed files with 32 additions and 21 deletions
|
@ -1022,14 +1022,15 @@ invalCellsWithTiles( BoardCtxt* board )
|
|||
return board->needsDrawing;
|
||||
} /* invalCellsWithTiles */
|
||||
|
||||
void
|
||||
XP_Bool
|
||||
checkScrollCell( void* p_board, XP_U16 col, XP_U16 row )
|
||||
{
|
||||
BoardCtxt* board = (BoardCtxt*)p_board;
|
||||
XP_Rect rect;
|
||||
XP_Bool moved = XP_FALSE;
|
||||
|
||||
if ( board->boardObscuresTray && board->trayVisState != TRAY_HIDDEN ) {
|
||||
|
||||
/* call getCellRect until the cell's on the board. */
|
||||
while ( !getCellRect( board, col, row, &rect ) ) {
|
||||
XP_U16 oldOffset = board_getYOffset( board );
|
||||
if ( rect.top < board->boardBounds.top ) {
|
||||
|
@ -1041,8 +1042,10 @@ checkScrollCell( void* p_board, XP_U16 col, XP_U16 row )
|
|||
XP_ASSERT( 0 );
|
||||
}
|
||||
board_setYOffset( board, oldOffset );
|
||||
moved = XP_TRUE;
|
||||
}
|
||||
}
|
||||
return moved;
|
||||
} /* checkScrollCell */
|
||||
|
||||
/* if any of a blank's neighbors is invalid, so must the blank become (since
|
||||
|
@ -1111,8 +1114,8 @@ scrollIfCan( BoardCtxt* board )
|
|||
|
||||
if ( scrolled ) {
|
||||
/* inval the rows that have been scrolled into view. I'm cheating
|
||||
making the client figure the inval rect, but Palm's the only
|
||||
client now and it does it so well.... */
|
||||
making the client figure the inval rect, but Palm's the first
|
||||
client and it does it so well.... */
|
||||
invalCellsUnderRect( board, &scrollR );
|
||||
} else {
|
||||
board_invalAll( board );
|
||||
|
@ -1782,7 +1785,6 @@ drawCell( BoardCtxt* board, XP_U16 col, XP_U16 row, XP_Bool skipBlanks )
|
|||
} else if ( dict_faceIsBitmap( dict, tile ) ) {
|
||||
bitmap = dict_getFaceBitmap( dict, tile, XP_FALSE );
|
||||
XP_ASSERT( !!bitmap );
|
||||
textP = (XP_UCHAR*)NULL;
|
||||
} else {
|
||||
(void)dict_tilesToString( dict, &tile, 1, ch, sizeof(ch) );
|
||||
textP = ch;
|
||||
|
|
|
@ -241,7 +241,7 @@ XP_UCHAR* getTileDrawInfo( const BoardCtxt* board, Tile tile, XP_Bool isBlank,
|
|||
XP_UCHAR* buf, XP_U16 len );
|
||||
XP_Bool dividerMoved( BoardCtxt* board, XP_U8 newLoc );
|
||||
|
||||
void checkScrollCell( void* p_board, XP_U16 col, XP_U16 row );
|
||||
XP_Bool checkScrollCell( void* p_board, XP_U16 col, XP_U16 row );
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
XP_Bool tray_moveCursor( BoardCtxt* board, XP_Key cursorKey,
|
||||
|
|
|
@ -411,18 +411,15 @@ dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
|||
(void)coordToCell( board, xx, yy, &newInfo.u.board.col,
|
||||
&newInfo.u.board.row );
|
||||
moving = (newInfo.u.board.col != ds->cur.u.board.col)
|
||||
|| (newInfo.u.board.row != ds->cur.u.board.row);
|
||||
if ( moving ) {
|
||||
checkScrollCell( board, newInfo.u.board.col, newInfo.u.board.row );
|
||||
}
|
||||
moving = moving || (OBJ_TRAY == ds->cur.obj);
|
||||
|| (newInfo.u.board.row != ds->cur.u.board.row)
|
||||
|| (OBJ_TRAY == ds->cur.obj);
|
||||
|
||||
} else if ( newInfo.obj == OBJ_TRAY ) {
|
||||
XP_Bool onDivider;
|
||||
XP_S16 index = pointToTileIndex( board, xx, yy, &onDivider );
|
||||
if ( !onDivider ) {
|
||||
if ( index < 0 ) { /* negative means onto empty part of tray.
|
||||
Force left. */
|
||||
if ( index < 0 ) { /* negative means onto empty part of
|
||||
tray. Force left. */
|
||||
index = model_getNumTilesInTray( board->model,
|
||||
board->selPlayer );
|
||||
if ( OBJ_TRAY == ds->start.obj ) {
|
||||
|
@ -438,16 +435,28 @@ dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
|||
}
|
||||
|
||||
if ( moving ) {
|
||||
if ( ds->dtype == DT_TILE ) {
|
||||
invalDragObjRange( board, &ds->cur, &newInfo );
|
||||
|
||||
/* This little hack lets us inval twice using the same code but
|
||||
only in the case where scrolling moves tiles. At a minimum
|
||||
it's necessary to inval the old position before a scroll and
|
||||
the new after. Otherwise if the platform scrolls by
|
||||
bit-blitting the dragged object will be scrolled before it's
|
||||
invalidated. */
|
||||
do {
|
||||
if ( ds->dtype == DT_TILE ) {
|
||||
invalDragObjRange( board, &ds->cur, &newInfo );
|
||||
#ifdef XWFEATURE_SEARCHLIMIT
|
||||
} else if ( ds->dtype == DT_HINTRGN ) {
|
||||
invalHintRectDiffs( board, &ds->cur, &newInfo );
|
||||
if ( !ds->didMove ) { /* first time through */
|
||||
invalCurHintRect( board, board->selPlayer );
|
||||
}
|
||||
} else if ( ds->dtype == DT_HINTRGN ) {
|
||||
invalHintRectDiffs( board, &ds->cur, &newInfo );
|
||||
if ( !ds->didMove ) { /* first time through */
|
||||
invalCurHintRect( board, board->selPlayer );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} while ( (newInfo.obj == OBJ_BOARD)
|
||||
&& checkScrollCell( board, newInfo.u.board.col,
|
||||
newInfo.u.board.row ) );
|
||||
|
||||
XP_MEMCPY( &ds->cur, &newInfo, sizeof(ds->cur) );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue