mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-05 20:45:49 +01:00
changes (commited earlier but now somehow missing) putting
scroll-related fields into a struct so vertical and horizontal can be handled by the same code; add to board_zoom out params indicating whether further zooming is possible.
This commit is contained in:
parent
477899e6aa
commit
da2cfa5934
8 changed files with 228 additions and 183 deletions
|
@ -223,9 +223,7 @@ static XP_Bool
|
|||
and_draw_boardBegin( DrawCtx* dctx, const XP_Rect* rect,
|
||||
XP_U16 cellWidth, XP_U16 cellHeight, DrawFocusState dfs )
|
||||
{
|
||||
AndDraw* draw = (AndDraw*)dctx;
|
||||
XP_Bool result = NULL != draw->jdraw;
|
||||
return result;
|
||||
return XP_TRUE;
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
|
|
|
@ -179,7 +179,8 @@ and_util_trayHiddenChange(XW_UtilCtxt* uc, XW_TrayVisState newState,
|
|||
}
|
||||
|
||||
static void
|
||||
and_util_yOffsetChange(XW_UtilCtxt* uc, XP_U16 oldOffset, XP_U16 newOffset )
|
||||
and_util_yOffsetChange(XW_UtilCtxt* uc, XP_U16 maxOffset,
|
||||
XP_U16 oldOffset, XP_U16 newOffset )
|
||||
{
|
||||
#if 0
|
||||
AndUtil* util = (AndUtil*)uc;
|
||||
|
|
|
@ -510,11 +510,14 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setPos
|
|||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1zoom
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jint zoomBy )
|
||||
( JNIEnv* env, jclass C, jint gamePtr, jint zoomBy, jbooleanArray jCanZoom )
|
||||
{
|
||||
jboolean result;
|
||||
XWJNI_START();
|
||||
result = board_zoom( state->game.board, zoomBy );
|
||||
XP_Bool canIn, canOut;
|
||||
result = board_zoom( state->game.board, zoomBy, &canIn, &canOut );
|
||||
jboolean canZoom[2] = { canIn, canOut };
|
||||
setBoolArray( env, jCanZoom, VSIZE(canZoom), canZoom );
|
||||
XWJNI_END();
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -203,10 +203,10 @@ board_makeFromStream( MPFORMAL XWStreamCtxt* stream, ModelCtxt* model,
|
|||
board = board_make( MPPARM(mpool) model, server, draw, util );
|
||||
|
||||
if ( version >= STREAM_VERS_4YOFFSET) {
|
||||
board->xOffset = (XP_U16)stream_getBits( stream, 4 );
|
||||
board->sd[SCROLL_H].offset = (XP_U16)stream_getBits( stream, 4 );
|
||||
board->zoomCount = (XP_U16)stream_getBits( stream, 4 );
|
||||
}
|
||||
board->yOffset = (XP_U16)
|
||||
board->sd[SCROLL_V].offset = (XP_U16)
|
||||
stream_getBits( stream, (version < STREAM_VERS_4YOFFSET) ? 2 : 4 );
|
||||
board->isFlipped = (XP_Bool)stream_getBits( stream, 1 );
|
||||
board->gameOver = (XP_Bool)stream_getBits( stream, 1 );
|
||||
|
@ -272,9 +272,9 @@ board_writeToStream( BoardCtxt* board, XWStreamCtxt* stream )
|
|||
{
|
||||
XP_U16 nPlayers, i;
|
||||
|
||||
stream_putBits( stream, 4, board->xOffset );
|
||||
stream_putBits( stream, 4, board->sd[SCROLL_H].offset );
|
||||
stream_putBits( stream, 4, board->zoomCount );
|
||||
stream_putBits( stream, 4, board->yOffset );
|
||||
stream_putBits( stream, 4, board->sd[SCROLL_V].offset );
|
||||
stream_putBits( stream, 1, board->isFlipped );
|
||||
stream_putBits( stream, 1, board->gameOver );
|
||||
stream_putBits( stream, 1, board->showColors );
|
||||
|
@ -379,23 +379,14 @@ board_setTimerLoc( BoardCtxt* board,
|
|||
board->timerBounds.height = timerHeight;
|
||||
} /* board_setTimerLoc */
|
||||
|
||||
void
|
||||
board_setScale( BoardCtxt* board, XP_U16 hScale, XP_U16 vScale )
|
||||
{
|
||||
if ( hScale != board->boardHScale || vScale != board->boardVScale ) {
|
||||
board->boardVScale = vScale;
|
||||
board->boardHScale = hScale;
|
||||
figureBoardRect( board );
|
||||
board_invalAll( board );
|
||||
}
|
||||
} /* board_setScale */
|
||||
|
||||
#if 0
|
||||
void
|
||||
board_getScale( BoardCtxt* board, XP_U16* hScale, XP_U16* vScale )
|
||||
{
|
||||
*hScale = board->boardHScale;
|
||||
*vScale = board->boardVScale;
|
||||
*hScale = board->sd[SCROLL_H].scale;
|
||||
*vScale = board->sd[SCROLL_V].scale;
|
||||
} /* board_getScale */
|
||||
#endif
|
||||
|
||||
XP_Bool
|
||||
board_prefsChanged( BoardCtxt* board, CommonPrefs* cp )
|
||||
|
@ -443,26 +434,31 @@ board_prefsChanged( BoardCtxt* board, CommonPrefs* cp )
|
|||
XP_Bool
|
||||
adjustXOffset( BoardCtxt* board, XP_S16 moveBy )
|
||||
{
|
||||
/* XP_LOGF( "%s(%d)", __func__, moveBy ); */
|
||||
XP_U16 nCols = model_numCols(board->model);
|
||||
XP_U16 nVisible = nCols - board->zoomCount;
|
||||
XP_S16 newOffset = board->xOffset - moveBy;
|
||||
XP_Bool changed = XP_FALSE;
|
||||
if ( 0 != moveBy ) {
|
||||
XP_U16 nCols = model_numCols(board->model);
|
||||
XP_U16 nVisible = nCols - board->zoomCount;
|
||||
ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
XP_S16 newOffset = hsd->offset - moveBy;
|
||||
|
||||
if ( newOffset < 0 ) {
|
||||
newOffset = 0;
|
||||
} else if ( newOffset + nVisible > nCols ) {
|
||||
newOffset = nCols - nVisible;
|
||||
if ( newOffset < 0 ) {
|
||||
newOffset = 0;
|
||||
} else if ( newOffset + nVisible > nCols ) {
|
||||
newOffset = nCols - nVisible;
|
||||
}
|
||||
|
||||
changed = board_setXOffset( board, newOffset );
|
||||
}
|
||||
|
||||
return board_setXOffset( board, newOffset );
|
||||
return changed;
|
||||
} /* adjustXOffset */
|
||||
|
||||
XP_Bool
|
||||
adjustYOffset( BoardCtxt* board, XP_S16 moveBy )
|
||||
{
|
||||
XP_U16 nVisible = board->lastVisibleRow - board->yOffset + 1;
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
XP_U16 nVisible = vsd->lastVisible - vsd->offset + 1;
|
||||
XP_U16 nRows = model_numRows(board->model);
|
||||
XP_S16 newOffset = board->yOffset - moveBy;
|
||||
XP_S16 newOffset = vsd->offset - moveBy;
|
||||
|
||||
if ( newOffset < 0 ) {
|
||||
newOffset = 0;
|
||||
|
@ -476,12 +472,12 @@ adjustYOffset( BoardCtxt* board, XP_S16 moveBy )
|
|||
static XP_Bool
|
||||
board_setXOffset( BoardCtxt* board, XP_U16 offset )
|
||||
{
|
||||
XP_Bool changed = offset != board->xOffset;
|
||||
ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
XP_Bool changed = offset != hsd->offset;
|
||||
if ( changed ) {
|
||||
board->xOffset = offset;
|
||||
board->lastVisibleCol = model_numCols(board->model)
|
||||
- board->zoomCount + offset;
|
||||
XP_LOGF( "%s: lastVisibleCol=%d", __func__, board->lastVisibleCol );
|
||||
hsd->offset = offset;
|
||||
hsd->lastVisible = model_numCols(board->model)
|
||||
- board->zoomCount + offset - 1;
|
||||
board_invalAll( board );
|
||||
}
|
||||
return changed;
|
||||
|
@ -490,30 +486,23 @@ board_setXOffset( BoardCtxt* board, XP_U16 offset )
|
|||
XP_Bool
|
||||
board_setYOffset( BoardCtxt* board, XP_U16 offset )
|
||||
{
|
||||
XP_U16 oldOffset = board->yOffset;
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
XP_U16 oldOffset = vsd->offset;
|
||||
XP_Bool result = oldOffset != offset;
|
||||
|
||||
if ( result ) {
|
||||
XP_U16 nVisible = board->lastVisibleRow - board->yOffset + 1;
|
||||
XP_U16 nVisible = vsd->lastVisible - vsd->offset + 1;
|
||||
XP_U16 nRows = model_numRows(board->model);
|
||||
|
||||
result = offset <= nRows - nVisible;
|
||||
if ( result ) {
|
||||
/* check if scrolling makes sense for this board in its current
|
||||
state. */
|
||||
XP_U16 visibleHeight = board->boardBounds.height;
|
||||
XP_U16 fullHeight = nRows * board->boardVScale;
|
||||
result = visibleHeight < fullHeight;
|
||||
|
||||
if ( result ) {
|
||||
invalSelTradeWindow( board );
|
||||
board->yOffset = offset;
|
||||
figureBoardRect( board );
|
||||
util_yOffsetChange( board->util, board->maxYOffset,
|
||||
oldOffset, offset );
|
||||
invalSelTradeWindow( board );
|
||||
board->needsDrawing = XP_TRUE;
|
||||
}
|
||||
invalSelTradeWindow( board );
|
||||
vsd->offset = offset;
|
||||
figureBoardRect( board );
|
||||
util_yOffsetChange( board->util, vsd->maxOffset,
|
||||
oldOffset, offset );
|
||||
invalSelTradeWindow( board );
|
||||
board->needsDrawing = XP_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -523,7 +512,8 @@ board_setYOffset( BoardCtxt* board, XP_U16 offset )
|
|||
XP_U16
|
||||
board_getYOffset( const BoardCtxt* board )
|
||||
{
|
||||
return board->yOffset;
|
||||
const ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
return vsd->offset;
|
||||
} /* board_getYOffset */
|
||||
|
||||
static XP_U16
|
||||
|
@ -538,10 +528,12 @@ adjustOffset( XP_U16 curOffset, XP_S16 zoomBy )
|
|||
}
|
||||
|
||||
XP_Bool
|
||||
board_zoom( BoardCtxt* board, XP_S16 zoomBy )
|
||||
board_zoom( BoardCtxt* board, XP_S16 zoomBy, XP_Bool* canIn, XP_Bool* canOut )
|
||||
{
|
||||
XP_Bool changed;
|
||||
XP_S16 zoomCount = board->zoomCount;
|
||||
ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
|
||||
XP_U16 maxCount = model_numCols( board->model ) - 2; /* 2 for scrolling */
|
||||
if ( board->boardBounds.width > board->boardBounds.height ) {
|
||||
|
@ -559,13 +551,21 @@ board_zoom( BoardCtxt* board, XP_S16 zoomBy )
|
|||
changed = zoomCount != board->zoomCount;
|
||||
if ( changed ) {
|
||||
/* Try to distribute the zoom */
|
||||
board->xOffset = adjustOffset( board->xOffset, zoomBy );
|
||||
board->yOffset = adjustOffset( board->yOffset, zoomBy );
|
||||
hsd->offset = adjustOffset( hsd->offset, zoomBy );
|
||||
vsd->offset = adjustOffset( vsd->offset, zoomBy );
|
||||
|
||||
board->zoomCount = zoomCount;
|
||||
figureBoardRect( board );
|
||||
board_invalAll( board );
|
||||
}
|
||||
|
||||
if ( !!canIn ) {
|
||||
*canIn = maxCount > zoomCount;
|
||||
}
|
||||
if ( !!canOut ) {
|
||||
*canOut = zoomCount > 0;
|
||||
}
|
||||
|
||||
return changed;
|
||||
} /* board_zoom */
|
||||
|
||||
|
@ -1043,10 +1043,13 @@ board_invalAllTiles( BoardCtxt* board )
|
|||
static void
|
||||
invalPerimeter( BoardCtxt* board )
|
||||
{
|
||||
XP_U16 lastCol = model_numCols( board->model ) - 1;
|
||||
XP_U16 firstAndLast = (1 << lastCol) | 1;
|
||||
XP_U16 firstRow = board->yOffset;
|
||||
XP_U16 lastRow = board->lastVisibleRow;
|
||||
ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
XP_U16 firstCol = hsd->offset;
|
||||
XP_U16 lastCol = hsd->lastVisible;
|
||||
XP_U16 firstAndLast = (1 << lastCol) | (1 << firstCol);
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
XP_U16 firstRow = vsd->offset;
|
||||
XP_U16 lastRow = vsd->lastVisible;
|
||||
|
||||
/* top and bottom rows */
|
||||
board->redrawFlags[firstRow] = ~0;
|
||||
|
@ -1140,42 +1143,46 @@ invalCellsWithTiles( BoardCtxt* board )
|
|||
return board->needsDrawing;
|
||||
} /* invalCellsWithTiles */
|
||||
|
||||
XP_Bool
|
||||
checkScrollCell( BoardCtxt* board, XP_U16 col, XP_U16 row )
|
||||
static XP_S16
|
||||
figureOffset(const BoardCtxt* board, SDIndex indx, XP_U16 col )
|
||||
{
|
||||
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_S16 moveBy = 1;
|
||||
if ( rect.top < board->boardBounds.top ) {
|
||||
/* do nothing; set to 1 above to prevent warning */
|
||||
} else if ( rect.top + rect.height >
|
||||
board->boardBounds.top + board->boardBounds.height ) {
|
||||
moveBy = -1;
|
||||
} else {
|
||||
/* what if a horizontal scroll's what's needed? */
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
moved = adjustYOffset( board, moveBy );
|
||||
XP_ASSERT( moved );
|
||||
}
|
||||
}
|
||||
return moved;
|
||||
} /* checkScrollCell */
|
||||
XP_S16 offset = 0;
|
||||
const ScrollData* sd = &board->sd[indx];
|
||||
if ( col < sd->offset ) {
|
||||
offset = sd->offset - col;
|
||||
} else if ( col > sd->lastVisible ) {
|
||||
offset = sd->lastVisible - col;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
onBorderCanScroll( const BoardCtxt* board, XP_U16 row, XP_S16* changeP )
|
||||
scrollIntoView( BoardCtxt* board, XP_U16 col, XP_U16 row )
|
||||
{
|
||||
XP_Bool moved;
|
||||
XP_S16 newOffset;
|
||||
|
||||
newOffset = figureOffset( board, SCROLL_H, col );
|
||||
moved = adjustXOffset( board, newOffset );
|
||||
|
||||
newOffset = figureOffset( board, SCROLL_V, row );
|
||||
moved = adjustYOffset( board, newOffset ) || moved;
|
||||
|
||||
return moved;
|
||||
} /* scrollIntoView */
|
||||
|
||||
XP_Bool
|
||||
onBorderCanScroll( const BoardCtxt* board, SDIndex indx,
|
||||
XP_U16 row /*or col */, XP_S16* changeP )
|
||||
{
|
||||
XP_Bool result;
|
||||
XP_S16 change = 0;
|
||||
XP_U16 yOffset = board_getYOffset( board );
|
||||
const ScrollData* sd = &board->sd[indx];
|
||||
XP_U16 offset = sd->offset;
|
||||
|
||||
if ( yOffset > 0 && row == yOffset ) {
|
||||
change = -yOffset;
|
||||
} else if ( row == board->lastVisibleRow ) {
|
||||
if ( offset > 0 && row == offset ) {
|
||||
change = -offset;
|
||||
} else if ( row == sd->lastVisible ) {
|
||||
XP_U16 lastRow = model_numRows(board->model) - 1;
|
||||
change = lastRow - row;
|
||||
}
|
||||
|
@ -1349,6 +1356,7 @@ setTrayVisState( BoardCtxt* board, XW_TrayVisState newState )
|
|||
XP_Bool nowHidden = newState == TRAY_HIDDEN;
|
||||
XP_U16 selPlayer = board->selPlayer;
|
||||
XP_U16 nVisible;
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
|
||||
/* redraw cells that are pending; whether tile is visible may
|
||||
change */
|
||||
|
@ -1391,7 +1399,7 @@ setTrayVisState( BoardCtxt* board, XW_TrayVisState newState )
|
|||
invalCurHintRect( board, selPlayer );
|
||||
#endif
|
||||
|
||||
nVisible = board->lastVisibleRow - board->yOffset + 1;
|
||||
nVisible = vsd->lastVisible - vsd->offset + 1;
|
||||
util_trayHiddenChange( board->util, board->trayVisState, nVisible );
|
||||
}
|
||||
return changed;
|
||||
|
@ -1610,22 +1618,28 @@ board_requestHint( BoardCtxt* board,
|
|||
return result || redraw;
|
||||
} /* board_requestHint */
|
||||
|
||||
static void
|
||||
static XP_Bool
|
||||
figureDims( XP_U16* edges, XP_U16 len, XP_U16 nVisible,
|
||||
XP_U16 increment, XP_U16 extra )
|
||||
{
|
||||
XP_Bool changed = XP_FALSE;
|
||||
XP_U16 ii;
|
||||
XP_U16 nAtStart = extra % nVisible;
|
||||
|
||||
increment += extra / nVisible;
|
||||
|
||||
for ( ii = 0; ii < len; ++ii ) {
|
||||
edges[ii] = increment;
|
||||
XP_U16 newVal = increment;
|
||||
if ( ii % nVisible < nAtStart ) {
|
||||
++edges[ii];
|
||||
++newVal;
|
||||
}
|
||||
if ( edges[ii] != newVal ) {
|
||||
edges[ii] = newVal;
|
||||
changed = XP_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
} /* figureDims */
|
||||
|
||||
static XP_U16
|
||||
figureHScale( BoardCtxt* board )
|
||||
|
@ -1636,14 +1650,17 @@ figureHScale( BoardCtxt* board )
|
|||
XP_U16 spares = board->boardBounds.width % nVisCols;
|
||||
|
||||
XP_U16 maxOffset = nCols - nVisCols;
|
||||
if ( board->xOffset > maxOffset ) {
|
||||
board->xOffset = maxOffset;
|
||||
ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
if ( hsd->offset > maxOffset ) {
|
||||
hsd->offset = maxOffset;
|
||||
}
|
||||
|
||||
board->lastVisibleCol = nCols - board->zoomCount + board->xOffset - 1;
|
||||
hsd->lastVisible = nCols - board->zoomCount + hsd->offset - 1;
|
||||
|
||||
figureDims( board->colWidths, VSIZE(board->colWidths), nVisCols,
|
||||
scale, spares );
|
||||
if ( figureDims( hsd->dims, VSIZE(hsd->dims), nVisCols,
|
||||
scale, spares ) ) {
|
||||
board_invalAll( board );
|
||||
}
|
||||
|
||||
return scale;
|
||||
} /* figureHScale */
|
||||
|
@ -1656,10 +1673,12 @@ figureBoardRect( BoardCtxt* board )
|
|||
XP_U16 nVisible;
|
||||
XP_U16 nRows = model_numRows( board->model );
|
||||
XP_U16 boardScale = figureHScale( board );
|
||||
ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
|
||||
if ( boardScale != board->boardHScale ) {
|
||||
if ( boardScale != hsd->scale ) {
|
||||
board_invalAll( board );
|
||||
board->boardHScale = boardScale;
|
||||
hsd->scale = boardScale;
|
||||
}
|
||||
|
||||
/* Figure height of board. Max height is with all rows visible and
|
||||
|
@ -1675,46 +1694,45 @@ figureBoardRect( BoardCtxt* board )
|
|||
maxHeight = board->trayBounds.top - board->boardBounds.top;
|
||||
}
|
||||
XP_U16 extra;
|
||||
XP_U16 oldYOffset = vsd->offset;
|
||||
if ( wantHeight <= maxHeight ) { /* yay! No need to scale */
|
||||
board->boardVScale = maxHeight / nRows;
|
||||
vsd->scale = maxHeight / nRows;
|
||||
extra = maxHeight % nRows;
|
||||
boardBounds.height = maxHeight;
|
||||
board->boardObscuresTray = XP_FALSE;
|
||||
board->yOffset = 0;
|
||||
vsd->offset = 0;
|
||||
nVisible = nRows;
|
||||
} else {
|
||||
XP_S16 maxYOffset;
|
||||
XP_U16 oldYOffset = board->yOffset;
|
||||
XP_Bool yChanged = XP_TRUE;
|
||||
/* Need to hide rows etc. */
|
||||
boardBounds.height = maxHeight;
|
||||
board->boardVScale = boardScale;
|
||||
vsd->scale = boardScale;
|
||||
|
||||
nVisible = maxHeight / boardScale;
|
||||
extra = maxHeight % boardScale;
|
||||
|
||||
maxYOffset = nRows - nVisible;
|
||||
if ( board->yOffset > maxYOffset ) {
|
||||
board->yOffset = maxYOffset;
|
||||
} else if ( maxYOffset != board->maxYOffset ) {
|
||||
board->maxYOffset = maxYOffset;
|
||||
if ( vsd->offset > maxYOffset ) {
|
||||
vsd->offset = maxYOffset;
|
||||
} else if ( maxYOffset != vsd->maxOffset ) {
|
||||
vsd->maxOffset = maxYOffset;
|
||||
} else {
|
||||
yChanged = XP_FALSE;
|
||||
}
|
||||
|
||||
if ( yChanged ) {
|
||||
util_yOffsetChange( board->util, maxYOffset, oldYOffset,
|
||||
board->yOffset );
|
||||
}
|
||||
/* XP_LOGF( "%s: maxYOffset: %d; board->yOffset: %d", __func__, */
|
||||
/* board->maxYOffset, board->yOffset ); */
|
||||
|
||||
board->boardObscuresTray = !trayHidden;
|
||||
board->boardObscuresTray = board->trayBounds.top < wantHeight
|
||||
&& board->trayBounds.left < (boardBounds.left + boardBounds.width);
|
||||
}
|
||||
board->lastVisibleRow = nVisible + board->yOffset - 1;
|
||||
util_yOffsetChange( board->util, nRows - nVisible, oldYOffset,
|
||||
vsd->offset );
|
||||
|
||||
figureDims( board->rowHeights, VSIZE(board->rowHeights), nVisible,
|
||||
board->boardVScale, extra );
|
||||
vsd->lastVisible = nVisible + vsd->offset - 1;
|
||||
|
||||
if ( figureDims( vsd->dims, VSIZE(vsd->dims), nVisible,
|
||||
vsd->scale, extra ) ) {
|
||||
board_invalAll( board );
|
||||
}
|
||||
|
||||
board->boardBounds = boardBounds;
|
||||
}
|
||||
|
@ -1740,12 +1758,14 @@ coordToCell( BoardCtxt* board, XP_S16 xx, XP_S16 yy, XP_U16* colP,
|
|||
XP_U16 maxCols = model_numCols( board->model );
|
||||
XP_S16 gotCol = -1;
|
||||
XP_S16 gotRow = -1;
|
||||
ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
|
||||
xx -= board->boardBounds.left;
|
||||
XP_ASSERT( xx >= 0 );
|
||||
|
||||
for ( col = board->xOffset; col < maxCols; ++col ) {
|
||||
xx -= board->colWidths[col];
|
||||
for ( col = hsd->offset; col < maxCols; ++col ) {
|
||||
xx -= hsd->dims[col];
|
||||
if ( xx < 0 ) {
|
||||
gotCol = col;
|
||||
break;
|
||||
|
@ -1754,8 +1774,8 @@ coordToCell( BoardCtxt* board, XP_S16 xx, XP_S16 yy, XP_U16* colP,
|
|||
|
||||
yy -= board->boardBounds.top;
|
||||
XP_ASSERT( yy >= 0 );
|
||||
for ( row = board->yOffset; row < maxCols; ++row ) {
|
||||
yy -= board->rowHeights[col];
|
||||
for ( row = vsd->offset; row < maxCols; ++row ) {
|
||||
yy -= vsd->dims[col];
|
||||
if ( yy < 0 ) {
|
||||
gotRow = row;
|
||||
break;
|
||||
|
@ -1783,20 +1803,22 @@ XP_Bool
|
|||
getCellRect( const BoardCtxt* board, XP_U16 col, XP_U16 row, XP_Rect* rect )
|
||||
{
|
||||
XP_U16 cur;
|
||||
XP_Bool onBoard = col >= board->xOffset && row >= board->yOffset
|
||||
&& col <= board->lastVisibleCol && row <= board->lastVisibleRow;
|
||||
const ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
const ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
XP_Bool onBoard = col >= hsd->offset && row >= vsd->offset
|
||||
&& col <= hsd->lastVisible && row <= vsd->lastVisible;
|
||||
|
||||
rect->left = board->boardBounds.left;
|
||||
for ( cur = board->xOffset; cur < col; ++cur ) {
|
||||
rect->left += board->colWidths[cur];
|
||||
for ( cur = hsd->offset; cur < col; ++cur ) {
|
||||
rect->left += hsd->dims[cur];
|
||||
}
|
||||
rect->width = board->colWidths[col];
|
||||
rect->width = hsd->dims[col];
|
||||
|
||||
rect->top = board->boardBounds.top;
|
||||
for ( cur = board->yOffset; cur < row; ++cur ) {
|
||||
rect->top += board->rowHeights[cur];
|
||||
for ( cur = vsd->offset; cur < row; ++cur ) {
|
||||
rect->top += vsd->dims[cur];
|
||||
}
|
||||
rect->height = board->rowHeights[row];
|
||||
rect->height = vsd->dims[row];
|
||||
|
||||
return onBoard;
|
||||
} /* getCellRect */
|
||||
|
@ -2629,7 +2651,7 @@ invalFocusOwner( BoardCtxt* board )
|
|||
if ( board->focusHasDived ) {
|
||||
BdCursorLoc loc = pti->bdCursor;
|
||||
invalCell( board, loc.col, loc.row );
|
||||
checkScrollCell( board, loc.col, loc.row );
|
||||
scrollIntoView( board, loc.col, loc.row );
|
||||
} else {
|
||||
#ifdef PERIMETER_FOCUS
|
||||
invalPerimeter( board );
|
||||
|
@ -2886,7 +2908,7 @@ board_moveCursor( BoardCtxt* board, XP_Key cursorKey, XP_Bool preflightOnly,
|
|||
loc.col = col;
|
||||
loc.row = row;
|
||||
pti->bdCursor = loc;
|
||||
checkScrollCell( board, col, row );
|
||||
scrollIntoView( board, col, row );
|
||||
}
|
||||
return changed;
|
||||
} /* board_moveCursor */
|
||||
|
@ -3045,7 +3067,7 @@ setArrowFor( BoardCtxt* board, XP_U16 player, XP_U16 col, XP_U16 row )
|
|||
arrow->col = (XP_U8)col;
|
||||
arrow->row = (XP_U8)row;
|
||||
|
||||
checkScrollCell( board, col, row );
|
||||
scrollIntoView( board, col, row );
|
||||
} /* setArrowFor */
|
||||
|
||||
static void
|
||||
|
@ -3134,7 +3156,7 @@ boardCellChanged( void* p_board, XP_U16 turn, XP_U16 modelCol, XP_U16 modelRow,
|
|||
}
|
||||
}
|
||||
|
||||
checkScrollCell( board, col, row );
|
||||
scrollIntoView( board, col, row );
|
||||
}
|
||||
|
||||
invalCell( (BoardCtxt*)p_board, col, row );
|
||||
|
|
|
@ -77,7 +77,8 @@ void board_reset( BoardCtxt* board );
|
|||
XP_Bool board_setYOffset( BoardCtxt* board, XP_U16 newOffset );
|
||||
XP_U16 board_getYOffset( const BoardCtxt* board );
|
||||
|
||||
XP_Bool board_zoom( BoardCtxt* board, XP_S16 zoomBy );
|
||||
XP_Bool board_zoom( BoardCtxt* board, XP_S16 zoomBy, XP_Bool* canIn,
|
||||
XP_Bool* canOut );
|
||||
|
||||
void board_setScoreboardLoc( BoardCtxt* board,
|
||||
XP_U16 scoreLeft, XP_U16 scoreTop,
|
||||
|
|
|
@ -95,15 +95,16 @@ invalOldPerimeter( BoardCtxt* board )
|
|||
{
|
||||
/* We need to inval the center of the row that's moving into the center
|
||||
from a border (at which point it got borders drawn on it.) */
|
||||
XP_S16 diff = board->yOffset - board->prevYScrollOffset;
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
XP_S16 diff = vsd->offset - board->prevYScrollOffset;
|
||||
XP_U16 firstRow, lastRow;
|
||||
XP_ASSERT( diff != 0 );
|
||||
if ( diff < 0 ) {
|
||||
/* moving up; inval row previously on bottom */
|
||||
firstRow = board->yOffset + 1;
|
||||
firstRow = vsd->offset + 1;
|
||||
lastRow = board->prevYScrollOffset;
|
||||
} else {
|
||||
XP_U16 nVisible = board->lastVisibleRow - board->yOffset + 1;
|
||||
XP_U16 nVisible = vsd->lastVisible - vsd->offset + 1;
|
||||
lastRow = board->prevYScrollOffset + nVisible - 1;
|
||||
firstRow = lastRow - diff + 1;
|
||||
}
|
||||
|
@ -232,9 +233,9 @@ static void
|
|||
drawBoard( BoardCtxt* board )
|
||||
{
|
||||
if ( board->needsDrawing
|
||||
&& draw_boardBegin( board->draw,
|
||||
&board->boardBounds,
|
||||
board->boardHScale, board->boardVScale,
|
||||
&& draw_boardBegin( board->draw, &board->boardBounds,
|
||||
board->sd[SCROLL_H].scale,
|
||||
board->sd[SCROLL_V].scale,
|
||||
dfsFor( board, OBJ_BOARD ) ) ) {
|
||||
|
||||
XP_Bool allDrawn = XP_TRUE;
|
||||
|
@ -242,6 +243,8 @@ drawBoard( BoardCtxt* board )
|
|||
XP_S16 col, row, nVisCols;
|
||||
ModelCtxt* model = board->model;
|
||||
BoardArrow const* arrow = NULL;
|
||||
ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
BlankQueue bq;
|
||||
|
||||
scrollIfCan( board ); /* this must happen before we count blanks
|
||||
|
@ -270,14 +273,14 @@ drawBoard( BoardCtxt* board )
|
|||
}
|
||||
|
||||
nVisCols = model_numCols( model ) - board->zoomCount;
|
||||
for ( row = board->yOffset; row <= board->lastVisibleRow; ++row ) {
|
||||
for ( row = vsd->offset; row <= vsd->lastVisible; ++row ) {
|
||||
XP_U16 rowFlags = board->redrawFlags[row];
|
||||
if ( rowFlags != 0 ) {
|
||||
XP_U16 failedBits = 0;
|
||||
for ( col = 0; col < nVisCols; ++col ) {
|
||||
XP_U16 colMask = 1 << (col + board->xOffset);
|
||||
XP_U16 colMask = 1 << (col + hsd->offset);
|
||||
if ( 0 != (rowFlags & colMask) ) {
|
||||
if ( !drawCell( board, col + board->xOffset,
|
||||
if ( !drawCell( board, col + hsd->offset,
|
||||
row, XP_TRUE )) {
|
||||
failedBits |= colMask;
|
||||
allDrawn = XP_FALSE;
|
||||
|
@ -451,7 +454,8 @@ static XP_Bool
|
|||
cellFocused( const BoardCtxt* board, XP_U16 col, XP_U16 row )
|
||||
{
|
||||
XP_Bool focussed = XP_FALSE;
|
||||
|
||||
const ScrollData* hsd = &board->sd[SCROLL_H];
|
||||
const ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
if ( (board->focussed == OBJ_BOARD) && !board->hideFocus ) {
|
||||
if ( board->focusHasDived ) {
|
||||
if ( (col == board->selInfo->bdCursor.col)
|
||||
|
@ -460,10 +464,10 @@ cellFocused( const BoardCtxt* board, XP_U16 col, XP_U16 row )
|
|||
}
|
||||
} else {
|
||||
#ifdef PERIMETER_FOCUS
|
||||
focussed = (col == 0)
|
||||
|| (col == model_numCols(board->model) - 1)
|
||||
|| (row == board->yOffset)
|
||||
|| (row == board->lastVisibleRow);
|
||||
focussed = (col == hsd->offset)
|
||||
|| (col == hsd->lastVisible)
|
||||
|| (row == vsd->offset)
|
||||
|| (row == vsd->lastVisible);
|
||||
#else
|
||||
focussed = XP_TRUE;
|
||||
#endif
|
||||
|
@ -513,6 +517,7 @@ drawDragTileIf( BoardCtxt* board )
|
|||
static XP_S16
|
||||
sumRowHeights( const BoardCtxt* board, XP_U16 row1, XP_U16 row2 )
|
||||
{
|
||||
const ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
XP_S16 sign = row1 > row2 ? -1 : 1;
|
||||
XP_S16 result, ii;
|
||||
if ( sign < 0 ) {
|
||||
|
@ -521,7 +526,7 @@ sumRowHeights( const BoardCtxt* board, XP_U16 row1, XP_U16 row2 )
|
|||
row2 = tmp;
|
||||
}
|
||||
for ( result = 0, ii = row1; ii < row2; ++ii ) {
|
||||
result += board->rowHeights[ii];
|
||||
result += vsd->dims[ii];
|
||||
}
|
||||
return result * sign;
|
||||
}
|
||||
|
@ -529,7 +534,8 @@ sumRowHeights( const BoardCtxt* board, XP_U16 row1, XP_U16 row2 )
|
|||
static void
|
||||
scrollIfCan( BoardCtxt* board )
|
||||
{
|
||||
if ( board->yOffset != board->prevYScrollOffset ) {
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
if ( vsd->offset != board->prevYScrollOffset ) {
|
||||
XP_Rect scrollR = board->boardBounds;
|
||||
XP_Bool scrolled;
|
||||
XP_S16 dist;
|
||||
|
@ -543,7 +549,7 @@ scrollIfCan( BoardCtxt* board )
|
|||
#endif
|
||||
invalSelTradeWindow( board );
|
||||
|
||||
dist = sumRowHeights( board, board->prevYScrollOffset, board->yOffset );
|
||||
dist = sumRowHeights( board, board->prevYScrollOffset, vsd->offset );
|
||||
scrolled = draw_vertScrollBoard( board->draw, &scrollR, dist,
|
||||
dfsFor( board, OBJ_BOARD ) );
|
||||
|
||||
|
@ -555,7 +561,7 @@ scrollIfCan( BoardCtxt* board )
|
|||
} else {
|
||||
board_invalAll( board );
|
||||
}
|
||||
board->prevYScrollOffset = board->yOffset;
|
||||
board->prevYScrollOffset = vsd->offset;
|
||||
}
|
||||
} /* scrollIfCan */
|
||||
|
||||
|
|
|
@ -116,6 +116,14 @@ typedef struct _PerTurnInfo {
|
|||
#endif
|
||||
} PerTurnInfo;
|
||||
|
||||
typedef struct _ScrollData {
|
||||
XP_U16 scale;
|
||||
XP_U16 offset;
|
||||
XP_U16 maxOffset;
|
||||
XP_U16 lastVisible;
|
||||
XP_U16 dims[MAX_COLS];
|
||||
} ScrollData;
|
||||
typedef enum { SCROLL_H, SCROLL_V, N_SCROLL_DIMS } SDIndex;
|
||||
|
||||
struct BoardCtxt {
|
||||
/* BoardVTable* vtable; */
|
||||
|
@ -125,14 +133,8 @@ struct BoardCtxt {
|
|||
XW_UtilCtxt* util;
|
||||
|
||||
struct CurGameInfo* gi;
|
||||
ScrollData sd[N_SCROLL_DIMS];
|
||||
|
||||
XP_U16 boardHScale;
|
||||
XP_U16 boardVScale;
|
||||
XP_U16 xOffset;
|
||||
XP_U16 yOffset;
|
||||
XP_U16 maxYOffset;
|
||||
XP_U16 lastVisibleRow;
|
||||
XP_U16 lastVisibleCol;
|
||||
XP_U16 preHideYOffset;
|
||||
XP_U16 prevYScrollOffset; /* represents where the last draw took place;
|
||||
used to see if bit scrolling can be used */
|
||||
|
@ -171,8 +173,6 @@ struct BoardCtxt {
|
|||
|
||||
XP_U16 star_row;
|
||||
XP_U16 zoomCount;
|
||||
XP_U16 colWidths[MAX_COLS];
|
||||
XP_U16 rowHeights[MAX_COLS];
|
||||
|
||||
/* Unless KEYBOARD_NAV is defined, this does not change */
|
||||
BoardObjectType focussed;
|
||||
|
@ -284,8 +284,9 @@ const XP_UCHAR* getTileDrawInfo( const BoardCtxt* board, Tile tile,
|
|||
XP_S16* value );
|
||||
XP_Bool dividerMoved( BoardCtxt* board, XP_U8 newLoc );
|
||||
|
||||
XP_Bool checkScrollCell( BoardCtxt* board, XP_U16 col, XP_U16 row );
|
||||
XP_Bool onBorderCanScroll( const BoardCtxt* board, XP_U16 row, XP_S16* change );
|
||||
XP_Bool scrollIntoView( BoardCtxt* board, XP_U16 col, XP_U16 row );
|
||||
XP_Bool onBorderCanScroll( const BoardCtxt* board, SDIndex indx, XP_U16 row,
|
||||
XP_S16* change );
|
||||
XP_Bool adjustXOffset( BoardCtxt* board, XP_S16 moveBy );
|
||||
XP_Bool adjustYOffset( BoardCtxt* board, XP_S16 moveBy );
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ extern "C" {
|
|||
|
||||
/* How many squares must scroll gesture take in to be recognized. */
|
||||
#ifndef SCROLL_DRAG_THRESHHOLD
|
||||
# define SCROLL_DRAG_THRESHHOLD 3
|
||||
# define SCROLL_DRAG_THRESHHOLD 1
|
||||
#endif
|
||||
|
||||
static XP_Bool dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
||||
|
@ -86,7 +86,8 @@ ddStartBoard( BoardCtxt* board, XP_U16 xx, XP_U16 yy )
|
|||
then the alt key determines it. I figure scrolling will be more
|
||||
common than hint dragging when both are possible, but you can turn
|
||||
hint dragging off, so if it's on that's probably what you want. */
|
||||
XP_Bool canScroll = board->lastVisibleRow < model_numRows(board->model);
|
||||
ScrollData* vsd = &board->sd[SCROLL_V];
|
||||
XP_Bool canScroll = vsd->lastVisible < model_numRows(board->model);
|
||||
if ( 0 ) {
|
||||
#ifdef XWFEATURE_SEARCHLIMIT
|
||||
} else if ( !board->gi->hintsNotAllowed && board->gi->allowHintRect
|
||||
|
@ -467,13 +468,13 @@ dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
|||
#endif
|
||||
} else if ( ds->dtype == DT_BOARD ) {
|
||||
if ( newInfo.obj == OBJ_BOARD ) {
|
||||
XP_S16 diff = newInfo.u.board.row - ds->cur.u.board.row;
|
||||
XP_S16 diff = newInfo.u.board.col - ds->cur.u.board.col;
|
||||
diff /= SCROLL_DRAG_THRESHHOLD;
|
||||
moving = adjustYOffset( board, diff );
|
||||
moving = adjustXOffset( board, diff );
|
||||
|
||||
diff = newInfo.u.board.col - ds->cur.u.board.col;
|
||||
diff = newInfo.u.board.row - ds->cur.u.board.row;
|
||||
diff /= SCROLL_DRAG_THRESHHOLD;
|
||||
moving = adjustXOffset( board, diff ) || moving;
|
||||
moving = adjustYOffset( board, diff ) || moving;
|
||||
}
|
||||
} else {
|
||||
if ( newInfo.obj == OBJ_BOARD ) {
|
||||
|
@ -572,13 +573,23 @@ scrollTimerProc( void* closure, XWTimerReason XP_UNUSED_DBG(why) )
|
|||
XP_ASSERT( why == TIMER_PENDOWN );
|
||||
|
||||
if ( ds->scrollTimerSet ) {
|
||||
XP_S16 change;
|
||||
XP_S16 changeX = 0;
|
||||
XP_S16 changeY = 0;
|
||||
ds->scrollTimerSet = XP_FALSE;
|
||||
if ( onBorderCanScroll( board, ds->cur.u.board.row, &change ) ) {
|
||||
XP_Bool canScroll = onBorderCanScroll( board, SCROLL_H,
|
||||
ds->cur.u.board.col, &changeX );
|
||||
canScroll = onBorderCanScroll( board, SCROLL_V, ds->cur.u.board.row,
|
||||
&changeY ) || canScroll;
|
||||
if ( canScroll ) {
|
||||
invalDragObj( board, &ds->cur );
|
||||
ds->cur.u.board.row += (change >0 ? 1 : -1);
|
||||
if ( checkScrollCell( board, ds->cur.u.board.col,
|
||||
ds->cur.u.board.row ) ) {
|
||||
if ( 0 != changeX ) {
|
||||
ds->cur.u.board.col += (changeX >0 ? 1 : -1);
|
||||
}
|
||||
if ( 0 != changeY ) {
|
||||
ds->cur.u.board.row += (changeY >0 ? 1 : -1);
|
||||
}
|
||||
if ( scrollIntoView( board, ds->cur.u.board.col,
|
||||
ds->cur.u.board.row ) ) {
|
||||
board_draw( board ); /* may fail, e.g. on wince */
|
||||
startScrollTimerIf( board );
|
||||
draw = XP_TRUE;
|
||||
|
@ -595,7 +606,9 @@ startScrollTimerIf( BoardCtxt* board )
|
|||
|
||||
if ( (ds->dtype == DT_TILE) && (ds->cur.obj == OBJ_BOARD) ) {
|
||||
XP_S16 ignore;
|
||||
if ( onBorderCanScroll( board, ds->cur.u.board.row, &ignore ) ) {
|
||||
if ( onBorderCanScroll( board, SCROLL_H, ds->cur.u.board.col, &ignore )
|
||||
|| onBorderCanScroll( board, SCROLL_V, ds->cur.u.board.row,
|
||||
&ignore ) ) {
|
||||
util_setTimer( board->util, TIMER_PENDOWN, 0,
|
||||
scrollTimerProc, (void*) board );
|
||||
ds->scrollTimerSet = XP_TRUE;
|
||||
|
|
Loading…
Add table
Reference in a new issue