mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-30 10:26:58 +01:00
fold hint-region-drag into dragdrpp, saving a bunch of code and
gaining scrolling during drag on small screens.
This commit is contained in:
parent
5c8756856d
commit
d00aa75a12
4 changed files with 274 additions and 265 deletions
|
@ -1,6 +1,6 @@
|
||||||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||||
/*
|
/*
|
||||||
* Copyright 1997 - 2007 by Eric House (xwords@eehouse.org). All rights
|
* Copyright 1997 - 2008 by Eric House (xwords@eehouse.org). All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -113,8 +113,6 @@ static XP_Bool board_moveArrow( BoardCtxt* board, XP_Key cursorKey );
|
||||||
#ifdef POINTER_SUPPORT
|
#ifdef POINTER_SUPPORT
|
||||||
static void drawDragTileIf( BoardCtxt* board );
|
static void drawDragTileIf( BoardCtxt* board );
|
||||||
#endif
|
#endif
|
||||||
static XP_Bool holdsPendingTile( BoardCtxt* board,
|
|
||||||
XP_U16 pencol, XP_U16 penrow );
|
|
||||||
|
|
||||||
#ifdef KEY_SUPPORT
|
#ifdef KEY_SUPPORT
|
||||||
static XP_Bool moveKeyTileToBoard( BoardCtxt* board, XP_Key cursorKey,
|
static XP_Bool moveKeyTileToBoard( BoardCtxt* board, XP_Key cursorKey,
|
||||||
|
@ -128,7 +126,6 @@ static XP_Bool invalFocusOwner( BoardCtxt* board );
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
static HintAtts figureHintAtts( BoardCtxt* board, XP_U16 col, XP_U16 row );
|
static HintAtts figureHintAtts( BoardCtxt* board, XP_U16 col, XP_U16 row );
|
||||||
static void invalCurHintRect( BoardCtxt* board, XP_U16 player );
|
|
||||||
static void clearCurHintRect( BoardCtxt* board );
|
static void clearCurHintRect( BoardCtxt* board );
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -508,7 +505,7 @@ invalSelTradeWindow( BoardCtxt* board )
|
||||||
} /* invalSelTradeWindow */
|
} /* invalSelTradeWindow */
|
||||||
|
|
||||||
#if defined POINTER_SUPPORT || defined KEYBOARD_NAV
|
#if defined POINTER_SUPPORT || defined KEYBOARD_NAV
|
||||||
static void
|
void
|
||||||
hideMiniWindow( BoardCtxt* board, XP_Bool destroy, MiniWindowType winType )
|
hideMiniWindow( BoardCtxt* board, XP_Bool destroy, MiniWindowType winType )
|
||||||
{
|
{
|
||||||
MiniWindowStuff* stuff = &board->miniWindowStuff[winType];
|
MiniWindowStuff* stuff = &board->miniWindowStuff[winType];
|
||||||
|
@ -737,22 +734,19 @@ timerFiredForPen( BoardCtxt* board )
|
||||||
const XP_UCHAR* text = (XP_UCHAR*)NULL;
|
const XP_UCHAR* text = (XP_UCHAR*)NULL;
|
||||||
XP_UCHAR buf[80];
|
XP_UCHAR buf[80];
|
||||||
|
|
||||||
if ( (board->penDownObject == OBJ_BOARD) && !dragDropInProgress(board)
|
if ( board->penDownObject == OBJ_BOARD ) {
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
if ( !dragDropInProgress( board ) || !dragDropHasMoved( board ) ) {
|
||||||
&& !board->hintDragInProgress
|
XP_U16 col, row;
|
||||||
#endif
|
XWBonusType bonus;
|
||||||
) {
|
|
||||||
XP_U16 col, row;
|
|
||||||
XWBonusType bonus;
|
|
||||||
|
|
||||||
coordToCell( board, board->penDownX, board->penDownY, &col,
|
coordToCell( board, board->penDownX, board->penDownY, &col,
|
||||||
&row );
|
&row );
|
||||||
bonus = util_getSquareBonus(board->util, board->model, col, row);
|
bonus = util_getSquareBonus(board->util, board->model, col, row);
|
||||||
if ( bonus != BONUS_NONE ) {
|
if ( bonus != BONUS_NONE ) {
|
||||||
text = draw_getMiniWText( board->draw, (XWMiniTextType)bonus );
|
text = draw_getMiniWText( board->draw, (XWMiniTextType)bonus );
|
||||||
|
}
|
||||||
|
board->penTimerFired = XP_TRUE;
|
||||||
}
|
}
|
||||||
board->penTimerFired = XP_TRUE;
|
|
||||||
|
|
||||||
} else if ( board->penDownObject == OBJ_SCORE ) {
|
} else if ( board->penDownObject == OBJ_SCORE ) {
|
||||||
XP_S16 player;
|
XP_S16 player;
|
||||||
LocalPlayer* lp;
|
LocalPlayer* lp;
|
||||||
|
@ -1027,7 +1021,7 @@ invalCellsWithTiles( BoardCtxt* board )
|
||||||
return board->needsDrawing;
|
return board->needsDrawing;
|
||||||
} /* invalCellsWithTiles */
|
} /* invalCellsWithTiles */
|
||||||
|
|
||||||
static void
|
void
|
||||||
checkScrollCell( void* p_board, XP_U16 col, XP_U16 row )
|
checkScrollCell( void* p_board, XP_U16 col, XP_U16 row )
|
||||||
{
|
{
|
||||||
BoardCtxt* board = (BoardCtxt*)p_board;
|
BoardCtxt* board = (BoardCtxt*)p_board;
|
||||||
|
@ -1965,6 +1959,7 @@ moveTileToArrowLoc( BoardCtxt* board, XP_U8 index )
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} /* moveTileToArrowLoc */
|
} /* moveTileToArrowLoc */
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
makeMiniWindowForText( BoardCtxt* board, const XP_UCHAR* text,
|
makeMiniWindowForText( BoardCtxt* board, const XP_UCHAR* text,
|
||||||
|
@ -2031,55 +2026,46 @@ figureHintAtts( BoardCtxt* board, XP_U16 col, XP_U16 row )
|
||||||
{
|
{
|
||||||
HintAtts result = HINT_BORDER_NONE;
|
HintAtts result = HINT_BORDER_NONE;
|
||||||
|
|
||||||
if ( board->trayVisState == TRAY_REVEALED && board->gi->allowHintRect ) {
|
/* while lets us break to exit... */
|
||||||
BdHintLimits limits = board->limits[board->selPlayer];
|
while ( board->trayVisState == TRAY_REVEALED && board->gi->allowHintRect ) {
|
||||||
|
BdHintLimits limits;
|
||||||
/* while lets us break to exit... */
|
if ( dragDropGetHintLimits( board, &limits ) ) {
|
||||||
while ( board->hasHintRect[board->selPlayer]
|
/* do nothing */
|
||||||
|| board->hintDragInProgress ) {
|
} else if ( board->hasHintRect[board->selPlayer] ) {
|
||||||
if ( col < limits.left ) break;
|
limits = board->limits[board->selPlayer];
|
||||||
if ( row < limits.top ) break;
|
} else {
|
||||||
if ( col > limits.right ) break;
|
|
||||||
if ( row > limits.bottom ) break;
|
|
||||||
|
|
||||||
if ( col == limits.left ) {
|
|
||||||
result |= HINT_BORDER_LEFT;
|
|
||||||
}
|
|
||||||
if ( col == limits.right ) {
|
|
||||||
result |= HINT_BORDER_RIGHT;
|
|
||||||
}
|
|
||||||
if ( row == limits.top) {
|
|
||||||
result |= HINT_BORDER_TOP;
|
|
||||||
}
|
|
||||||
if ( row == limits.bottom ) {
|
|
||||||
result |= HINT_BORDER_BOTTOM;
|
|
||||||
}
|
|
||||||
#ifndef XWFEATURE_SEARCHLIMIT_DOCENTERS
|
|
||||||
if ( result == HINT_BORDER_NONE ) {
|
|
||||||
result = HINT_BORDER_CENTER;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( col < limits.left ) break;
|
||||||
|
if ( row < limits.top ) break;
|
||||||
|
if ( col > limits.right ) break;
|
||||||
|
if ( row > limits.bottom ) break;
|
||||||
|
|
||||||
|
if ( col == limits.left ) {
|
||||||
|
result |= HINT_BORDER_LEFT;
|
||||||
|
}
|
||||||
|
if ( col == limits.right ) {
|
||||||
|
result |= HINT_BORDER_RIGHT;
|
||||||
|
}
|
||||||
|
if ( row == limits.top) {
|
||||||
|
result |= HINT_BORDER_TOP;
|
||||||
|
}
|
||||||
|
if ( row == limits.bottom ) {
|
||||||
|
result |= HINT_BORDER_BOTTOM;
|
||||||
|
}
|
||||||
|
#ifndef XWFEATURE_SEARCHLIMIT_DOCENTERS
|
||||||
|
if ( result == HINT_BORDER_NONE ) {
|
||||||
|
result = HINT_BORDER_CENTER;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} /* figureHintAtts */
|
} /* figureHintAtts */
|
||||||
|
|
||||||
static XP_Bool
|
void
|
||||||
startHintRegionDrag( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
|
||||||
{
|
|
||||||
XP_Bool needsRedraw = XP_FALSE;
|
|
||||||
XP_U16 col, row;
|
|
||||||
|
|
||||||
coordToCell( board, x, y, &col, &row );
|
|
||||||
board->hintDragStartCol = board->hintDragCurCol = col;
|
|
||||||
board->hintDragStartRow = board->hintDragCurRow = row;
|
|
||||||
|
|
||||||
return needsRedraw;
|
|
||||||
} /* startHintRegionDrag */
|
|
||||||
|
|
||||||
static void
|
|
||||||
invalCellRegion( BoardCtxt* board, XP_U16 colA, XP_U16 rowA, XP_U16 colB,
|
invalCellRegion( BoardCtxt* board, XP_U16 colA, XP_U16 rowA, XP_U16 colB,
|
||||||
XP_U16 rowB )
|
XP_U16 rowB )
|
||||||
{
|
{
|
||||||
|
@ -2114,7 +2100,7 @@ invalCellRegion( BoardCtxt* board, XP_U16 colA, XP_U16 rowA, XP_U16 colB,
|
||||||
}
|
}
|
||||||
} /* invalCellRegion */
|
} /* invalCellRegion */
|
||||||
|
|
||||||
static void
|
void
|
||||||
invalCurHintRect( BoardCtxt* board, XP_U16 player )
|
invalCurHintRect( BoardCtxt* board, XP_U16 player )
|
||||||
{
|
{
|
||||||
BdHintLimits* limits = &board->limits[player];
|
BdHintLimits* limits = &board->limits[player];
|
||||||
|
@ -2129,122 +2115,14 @@ clearCurHintRect( BoardCtxt* board )
|
||||||
board->hasHintRect[board->selPlayer] = XP_FALSE;
|
board->hasHintRect[board->selPlayer] = XP_FALSE;
|
||||||
} /* clearCurHintRect */
|
} /* clearCurHintRect */
|
||||||
|
|
||||||
static void
|
|
||||||
setHintRect( BoardCtxt* board )
|
|
||||||
{
|
|
||||||
BdHintLimits limits;
|
|
||||||
if ( board->hintDragStartRow < board->hintDragCurRow ) {
|
|
||||||
limits.top = board->hintDragStartRow;
|
|
||||||
limits.bottom = board->hintDragCurRow;
|
|
||||||
} else {
|
|
||||||
limits.top = board->hintDragCurRow;
|
|
||||||
limits.bottom = board->hintDragStartRow;
|
|
||||||
}
|
|
||||||
if ( board->hintDragStartCol < board->hintDragCurCol ) {
|
|
||||||
limits.left = board->hintDragStartCol;
|
|
||||||
limits.right = board->hintDragCurCol;
|
|
||||||
} else {
|
|
||||||
limits.left = board->hintDragCurCol;
|
|
||||||
limits.right = board->hintDragStartCol;
|
|
||||||
}
|
|
||||||
|
|
||||||
board->limits[board->selPlayer] = limits;
|
|
||||||
board->hasHintRect[board->selPlayer] = XP_TRUE;
|
|
||||||
} /* setHintRect */
|
|
||||||
|
|
||||||
static void
|
|
||||||
invalHintRectDiffs( BoardCtxt* board, BdHintLimits* newLim,
|
|
||||||
BdHintLimits* oldLim )
|
|
||||||
{
|
|
||||||
/* These two regions will generally have close to 50% of their borders in
|
|
||||||
common. Try not to inval what needn't be inval'd. But at the moment
|
|
||||||
performance seems good enough without adding the complexity and new
|
|
||||||
bugs... */
|
|
||||||
invalCellRegion( board, newLim->left, newLim->top,
|
|
||||||
newLim->right, newLim->bottom );
|
|
||||||
invalCellRegion( board, oldLim->left, oldLim->top,
|
|
||||||
oldLim->right, oldLim->bottom );
|
|
||||||
|
|
||||||
/* The challenge in doing a smarter diff is that some squares need to be
|
|
||||||
invalidated even if they're part of the borders of both limits rects,
|
|
||||||
in particular if one is a corner of one and just a side of another.
|
|
||||||
One simple but expensive way of accounting for this would be to call
|
|
||||||
figureHintAtts() on each square in the borders of both rects and
|
|
||||||
invalidate when the hintAttributes aren't the same for both. That
|
|
||||||
misses an opportunity to avoid doing any calculations on those border
|
|
||||||
squares that clearly haven't changed at all.
|
|
||||||
*/
|
|
||||||
} /* invalHintRectDiffs */
|
|
||||||
|
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
continueHintRegionDrag( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
handlePenDownOnBoard( BoardCtxt* board, XP_U16 xx, XP_U16 yy )
|
||||||
{
|
|
||||||
XP_Bool needsRedraw = XP_FALSE;
|
|
||||||
|
|
||||||
XP_U16 col, row;
|
|
||||||
if ( coordToCell( board, x, y, &col, &row ) ) {
|
|
||||||
XP_U16 selPlayer = board->selPlayer;
|
|
||||||
|
|
||||||
checkScrollCell( board, col, row );
|
|
||||||
|
|
||||||
if ( col != board->hintDragCurCol || row != board->hintDragCurRow ) {
|
|
||||||
BdHintLimits oldHL;
|
|
||||||
|
|
||||||
needsRedraw = XP_TRUE;
|
|
||||||
|
|
||||||
board->hintDragInProgress = XP_TRUE;
|
|
||||||
|
|
||||||
/* Now that we've moved, this isn't a timer thing. Clean up any
|
|
||||||
artifacts. */
|
|
||||||
board->penTimerFired = XP_FALSE;
|
|
||||||
if ( valHintMiniWindowActive( board ) ) {
|
|
||||||
hideMiniWindow( board, XP_TRUE, MINIWINDOW_VALHINT );
|
|
||||||
}
|
|
||||||
|
|
||||||
board->hintDragCurCol = col;
|
|
||||||
board->hintDragCurRow = row;
|
|
||||||
|
|
||||||
oldHL = board->limits[selPlayer];
|
|
||||||
setHintRect( board );
|
|
||||||
invalHintRectDiffs( board, &board->limits[selPlayer], &oldHL );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return needsRedraw;
|
|
||||||
} /* continueHintRegionDrag */
|
|
||||||
|
|
||||||
static XP_Bool
|
|
||||||
finishHintRegionDrag( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
|
||||||
{
|
|
||||||
XP_Bool needsRedraw = XP_FALSE;
|
|
||||||
XP_Bool makeActive;
|
|
||||||
|
|
||||||
XP_ASSERT( board->hintDragInProgress );
|
|
||||||
needsRedraw = continueHintRegionDrag( board, x, y );
|
|
||||||
|
|
||||||
/* Now check if the whole drag ended above where it started. If yes, it
|
|
||||||
means erase! */
|
|
||||||
makeActive = board->hintDragStartRow <= board->hintDragCurRow;
|
|
||||||
|
|
||||||
board->hasHintRect[board->selPlayer] = makeActive;
|
|
||||||
if ( !makeActive ) {
|
|
||||||
invalCurHintRect( board, board->selPlayer );
|
|
||||||
needsRedraw = XP_TRUE;
|
|
||||||
}
|
|
||||||
board_resetEngine( board );
|
|
||||||
|
|
||||||
return needsRedraw;
|
|
||||||
} /* finishHintRegionDrag */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static XP_Bool
|
|
||||||
handlePenDownOnBoard( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
|
||||||
{
|
{
|
||||||
XP_Bool result = XP_FALSE;
|
XP_Bool result = XP_FALSE;
|
||||||
XP_U16 col, row;
|
XP_U16 col, row;
|
||||||
/* Start a timer no matter what. After it fires we'll decide whether it's
|
/* Start a timer no matter what. After it fires we'll decide whether it's
|
||||||
appropriate to handle it. No. That's too expensive */
|
appropriate to handle it. No. That's too expensive */
|
||||||
if ( TRADE_IN_PROGRESS(board) && ptOnTradeWindow( board, x, y ) ) {
|
if ( TRADE_IN_PROGRESS(board) && ptOnTradeWindow( board, xx, yy ) ) {
|
||||||
return XP_FALSE;
|
return XP_FALSE;
|
||||||
}
|
}
|
||||||
util_setTimer( board->util, TIMER_PENDOWN, 0, p_board_timerFired, board );
|
util_setTimer( board->util, TIMER_PENDOWN, 0, p_board_timerFired, board );
|
||||||
|
@ -2252,17 +2130,11 @@ handlePenDownOnBoard( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
||||||
/* As a first cut, you start a hint-region drag unless the cell is
|
/* As a first cut, you start a hint-region drag unless the cell is
|
||||||
occupied by a non-committed cell. */
|
occupied by a non-committed cell. */
|
||||||
|
|
||||||
coordToCell( board, x, y, &col, &row );
|
coordToCell( board, xx, yy, &col, &row );
|
||||||
if ( (board->trayVisState == TRAY_REVEALED)
|
if ( (board->trayVisState == TRAY_REVEALED)
|
||||||
&& !board->tradeInProgress[board->selPlayer]
|
&& !board->tradeInProgress[board->selPlayer] ) {
|
||||||
&& holdsPendingTile( board, col, row ) ) {
|
result = dragDropStart( board, OBJ_BOARD, xx, yy );
|
||||||
result = dragDropStart( board, OBJ_BOARD, col, row );
|
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
|
||||||
} else if ( board->gi->allowHintRect
|
|
||||||
&& (board->trayVisState == TRAY_REVEALED) ) {
|
|
||||||
result = startHintRegionDrag( board, x, y );
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} /* handlePenDownOnBoard */
|
} /* handlePenDownOnBoard */
|
||||||
|
@ -2403,19 +2275,10 @@ board_handlePenDown( BoardCtxt* board, XP_U16 x, XP_U16 y, XP_Bool* handled )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
XP_Bool
|
XP_Bool
|
||||||
board_handlePenMove( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
board_handlePenMove( BoardCtxt* board, XP_U16 xx, XP_U16 yy )
|
||||||
{
|
{
|
||||||
XP_Bool result = XP_FALSE;
|
XP_Bool result = dragDropInProgress(board)
|
||||||
|
&& dragDropContinue( board, xx, yy );
|
||||||
if ( dragDropInProgress(board) ) {
|
|
||||||
result = dragDropContinue( board, x, y ) != 0;
|
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
|
||||||
} else if ( board->gi->allowHintRect
|
|
||||||
&& board->trayVisState == TRAY_REVEALED ) {
|
|
||||||
result = continueHintRegionDrag( board, x, y );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} /* board_handlePenMove */
|
} /* board_handlePenMove */
|
||||||
|
|
||||||
|
@ -2506,7 +2369,7 @@ tryMoveArrow( BoardCtxt* board, XP_U16 col, XP_U16 row )
|
||||||
return result;
|
return result;
|
||||||
} /* tryMoveArrow */
|
} /* tryMoveArrow */
|
||||||
|
|
||||||
static XP_Bool
|
XP_Bool
|
||||||
holdsPendingTile( BoardCtxt* board, XP_U16 pencol, XP_U16 penrow )
|
holdsPendingTile( BoardCtxt* board, XP_U16 pencol, XP_U16 penrow )
|
||||||
{
|
{
|
||||||
Tile tile;
|
Tile tile;
|
||||||
|
@ -2584,16 +2447,12 @@ board_handlePenUp( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
||||||
draw = dragDropEnd( board, x, y, &dragged );
|
draw = dragDropEnd( board, x, y, &dragged );
|
||||||
}
|
}
|
||||||
if ( dragged ) {
|
if ( dragged ) {
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
/* do nothing further */
|
||||||
} else if ( board->hintDragInProgress ) {
|
|
||||||
XP_ASSERT( board->gi->allowHintRect );
|
|
||||||
draw = finishHintRegionDrag( board, x, y ) || draw;
|
|
||||||
#endif
|
|
||||||
} else if ( board->penTimerFired ) {
|
} else if ( board->penTimerFired ) {
|
||||||
if ( valHintMiniWindowActive( board ) ) {
|
if ( valHintMiniWindowActive( board ) ) {
|
||||||
hideMiniWindow( board, XP_TRUE, MINIWINDOW_VALHINT );
|
hideMiniWindow( board, XP_TRUE, MINIWINDOW_VALHINT );
|
||||||
draw = XP_TRUE;
|
|
||||||
}
|
}
|
||||||
|
draw = XP_TRUE; /* might have cancelled a drag */
|
||||||
/* Need to clean up if there's been any dragging happening */
|
/* Need to clean up if there's been any dragging happening */
|
||||||
board->penTimerFired = XP_FALSE;
|
board->penTimerFired = XP_FALSE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2635,9 +2494,6 @@ board_handlePenUp( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
|
||||||
board->hintDragInProgress = XP_FALSE;
|
|
||||||
#endif
|
|
||||||
return draw;
|
return draw;
|
||||||
} /* board_handlePenUp */
|
} /* board_handlePenUp */
|
||||||
#endif /* #ifdef POINTER_SUPPORT */
|
#endif /* #ifdef POINTER_SUPPORT */
|
||||||
|
|
|
@ -43,12 +43,24 @@ typedef struct _DragObjInfo {
|
||||||
} u;
|
} u;
|
||||||
} DragObjInfo;
|
} DragObjInfo;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DT_NONE
|
||||||
|
,DT_DIVIDER
|
||||||
|
,DT_TILE
|
||||||
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
|
,DT_HINTRGN
|
||||||
|
#endif
|
||||||
|
} DragType;
|
||||||
|
|
||||||
|
|
||||||
typedef struct DragState {
|
typedef struct DragState {
|
||||||
XP_Bool dragInProgress;
|
DragType dtype;
|
||||||
XP_Bool dividerOnly; /* special case; most other stuff ignored */
|
|
||||||
XP_Bool didMove; /* there was change during the drag; not a
|
XP_Bool didMove; /* there was change during the drag; not a
|
||||||
tap */
|
tap */
|
||||||
XP_Bool isBlank; /* cache rather than lookup in model */
|
XP_Bool isBlank; /* cache rather than lookup in model */
|
||||||
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
|
/* XP_Bool hintRectInvalidated; /\* only inval cur rect once after start drag *\/ */
|
||||||
|
#endif
|
||||||
Tile tile; /* cache rather than lookup in model */
|
Tile tile; /* cache rather than lookup in model */
|
||||||
DragObjInfo start;
|
DragObjInfo start;
|
||||||
DragObjInfo cur;
|
DragObjInfo cur;
|
||||||
|
@ -175,10 +187,6 @@ struct BoardCtxt {
|
||||||
XP_Bool showColors;
|
XP_Bool showColors;
|
||||||
|
|
||||||
#ifdef XWFEATURE_SEARCHLIMIT
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
XP_U16 hintDragStartCol, hintDragStartRow;
|
|
||||||
XP_U16 hintDragCurCol, hintDragCurRow;
|
|
||||||
XP_Bool hintDragInProgress;
|
|
||||||
|
|
||||||
XP_Bool hasHintRect[MAX_NUM_PLAYERS];
|
XP_Bool hasHintRect[MAX_NUM_PLAYERS];
|
||||||
BdHintLimits limits[MAX_NUM_PLAYERS];
|
BdHintLimits limits[MAX_NUM_PLAYERS];
|
||||||
#endif
|
#endif
|
||||||
|
@ -211,20 +219,33 @@ XP_Bool coordToCell( BoardCtxt* board, XP_U16 x, XP_U16 y, XP_U16* colP,
|
||||||
XP_U16* rowP );
|
XP_U16* rowP );
|
||||||
XP_Bool cellOccupied( BoardCtxt* board, XP_U16 col, XP_U16 row,
|
XP_Bool cellOccupied( BoardCtxt* board, XP_U16 col, XP_U16 row,
|
||||||
XP_Bool inclPending );
|
XP_Bool inclPending );
|
||||||
|
XP_Bool holdsPendingTile( BoardCtxt* board, XP_U16 pencol, XP_U16 penrow );
|
||||||
|
|
||||||
XP_Bool moveTileToBoard( BoardCtxt* board, XP_U16 col, XP_U16 row,
|
XP_Bool moveTileToBoard( BoardCtxt* board, XP_U16 col, XP_U16 row,
|
||||||
XP_U16 tileIndex, Tile blankFace );
|
XP_U16 tileIndex, Tile blankFace );
|
||||||
|
|
||||||
void invalTilesUnderRect( BoardCtxt* board, XP_Rect* rect );
|
void invalTilesUnderRect( BoardCtxt* board, XP_Rect* rect );
|
||||||
|
void invalCellRegion( BoardCtxt* board, XP_U16 colA, XP_U16 rowA, XP_U16 colB,
|
||||||
|
XP_U16 rowB );
|
||||||
void invalDragObj( BoardCtxt* board, const DragObjInfo* di );
|
void invalDragObj( BoardCtxt* board, const DragObjInfo* di );
|
||||||
void invalTrayTilesAbove( BoardCtxt* board, XP_U16 tileIndex );
|
void invalTrayTilesAbove( BoardCtxt* board, XP_U16 tileIndex );
|
||||||
void invalTrayTilesBetween( BoardCtxt* board, XP_U16 tileIndex1,
|
void invalTrayTilesBetween( BoardCtxt* board, XP_U16 tileIndex1,
|
||||||
XP_U16 tileIndex2 );
|
XP_U16 tileIndex2 );
|
||||||
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
|
void invalCurHintRect( BoardCtxt* board, XP_U16 player );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void hideMiniWindow( BoardCtxt* board, XP_Bool destroy,
|
||||||
|
MiniWindowType winType );
|
||||||
|
|
||||||
void moveTileInTray( BoardCtxt* board, XP_U16 moveTo, XP_U16 moveFrom );
|
void moveTileInTray( BoardCtxt* board, XP_U16 moveTo, XP_U16 moveFrom );
|
||||||
XP_UCHAR* getTileDrawInfo( const BoardCtxt* board, Tile tile, XP_Bool isBlank,
|
XP_UCHAR* getTileDrawInfo( const BoardCtxt* board, Tile tile, XP_Bool isBlank,
|
||||||
XP_Bitmap* bitmap, XP_S16* value,
|
XP_Bitmap* bitmap, XP_S16* value,
|
||||||
XP_UCHAR* buf, XP_U16 len );
|
XP_UCHAR* buf, XP_U16 len );
|
||||||
XP_Bool dividerMoved( BoardCtxt* board, XP_U8 newLoc );
|
XP_Bool dividerMoved( BoardCtxt* board, XP_U8 newLoc );
|
||||||
|
|
||||||
|
void checkScrollCell( void* p_board, XP_U16 col, XP_U16 row );
|
||||||
|
|
||||||
#ifdef KEYBOARD_NAV
|
#ifdef KEYBOARD_NAV
|
||||||
XP_Bool tray_moveCursor( BoardCtxt* board, XP_Key cursorKey,
|
XP_Bool tray_moveCursor( BoardCtxt* board, XP_Key cursorKey,
|
||||||
XP_Bool preflightOnly, XP_Bool* up );
|
XP_Bool preflightOnly, XP_Bool* up );
|
||||||
|
|
|
@ -23,38 +23,60 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "dragdrpp.h"
|
#include "dragdrpp.h"
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
static XP_Bool dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
static XP_Bool dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
||||||
BoardObjectType* onWhichP );
|
BoardObjectType* onWhichP );
|
||||||
static void invalDragObjRange( BoardCtxt* board, const DragObjInfo* from,
|
static void invalDragObjRange( BoardCtxt* board, const DragObjInfo* from,
|
||||||
const DragObjInfo* to );
|
const DragObjInfo* to );
|
||||||
|
static void invalHintRectDiffs( BoardCtxt* board, const DragObjInfo* cur,
|
||||||
|
const DragObjInfo* nxt );
|
||||||
|
static void setLimitsFrom( const BoardCtxt* board, BdHintLimits* limits );
|
||||||
|
|
||||||
XP_Bool
|
XP_Bool
|
||||||
dragDropInProgress( const BoardCtxt* board )
|
dragDropInProgress( const BoardCtxt* board )
|
||||||
{
|
{
|
||||||
const DragState* ds = &board->dragState;
|
const DragState* ds = &board->dragState;
|
||||||
/* LOG_RETURNF( "%d", ds->dragInProgress ); */
|
/* LOG_RETURNF( "%d", ds->dragInProgress ); */
|
||||||
return ds->dragInProgress;
|
return ds->dtype != DT_NONE;
|
||||||
}
|
} /* dragDropInProgress */
|
||||||
|
|
||||||
|
XP_Bool
|
||||||
|
dragDropHasMoved( const BoardCtxt* board )
|
||||||
|
{
|
||||||
|
return dragDropInProgress(board) && board->dragState.didMove;
|
||||||
|
} /* dragDropHasMoved */
|
||||||
|
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
ddStartBoard( BoardCtxt* board, XP_U16 col, XP_U16 row )
|
ddStartBoard( BoardCtxt* board, XP_U16 xx, XP_U16 yy )
|
||||||
{
|
{
|
||||||
DragState* ds = &board->dragState;
|
DragState* ds = &board->dragState;
|
||||||
XP_Bool ignore, found;
|
XP_Bool found;
|
||||||
XP_U16 modelc, modelr;
|
XP_U16 col, row;
|
||||||
|
|
||||||
|
found = coordToCell( board, xx, yy, &col, &row );
|
||||||
|
XP_ASSERT( found );
|
||||||
|
|
||||||
|
if ( holdsPendingTile( board, col, row ) ) {
|
||||||
|
XP_U16 modelc, modelr;
|
||||||
|
XP_Bool ignore;
|
||||||
|
|
||||||
|
ds->dtype = DT_TILE;
|
||||||
|
flipIf( board, col, row, &modelc, &modelr );
|
||||||
|
|
||||||
|
found = model_getTile( board->model, modelc, modelr, XP_TRUE,
|
||||||
|
board->selPlayer, &ds->tile, &ds->isBlank,
|
||||||
|
&ignore, &ignore );
|
||||||
|
XP_ASSERT( found );
|
||||||
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
|
} else if ( board->gi->allowHintRect ) {
|
||||||
|
ds->dtype = DT_HINTRGN;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
ds->start.u.board.col = col;
|
ds->start.u.board.col = col;
|
||||||
ds->start.u.board.row = row;
|
ds->start.u.board.row = row;
|
||||||
|
|
||||||
flipIf( board, col, row, &modelc, &modelr );
|
return ds->dtype != DT_NONE;
|
||||||
|
|
||||||
found = model_getTile( board->model, modelc, modelr, XP_TRUE,
|
|
||||||
board->selPlayer, &ds->tile, &ds->isBlank,
|
|
||||||
&ignore, &ignore );
|
|
||||||
XP_ASSERT( found );
|
|
||||||
|
|
||||||
return XP_TRUE;
|
|
||||||
} /* ddStartBoard */
|
} /* ddStartBoard */
|
||||||
|
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
|
@ -69,9 +91,10 @@ ddStartTray( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
||||||
if ( canDrag ) {
|
if ( canDrag ) {
|
||||||
XP_S16 selPlayer = board->selPlayer;
|
XP_S16 selPlayer = board->selPlayer;
|
||||||
if ( onDivider ) {
|
if ( onDivider ) {
|
||||||
ds->dividerOnly = XP_TRUE;
|
|
||||||
board->dividerInvalid = XP_TRUE;
|
board->dividerInvalid = XP_TRUE;
|
||||||
ds->start.u.tray.index = board->dividerLoc[selPlayer];
|
ds->start.u.tray.index = board->dividerLoc[selPlayer];
|
||||||
|
|
||||||
|
ds->dtype = DT_DIVIDER;
|
||||||
} else {
|
} else {
|
||||||
Tile tile;
|
Tile tile;
|
||||||
tile = model_getPlayerTile( board->model, selPlayer, index );
|
tile = model_getPlayerTile( board->model, selPlayer, index );
|
||||||
|
@ -84,6 +107,8 @@ ddStartTray( BoardCtxt* board, XP_U16 x, XP_U16 y )
|
||||||
/* during drag the moving tile is drawn as selected, so inval
|
/* during drag the moving tile is drawn as selected, so inval
|
||||||
currently selected tile. */
|
currently selected tile. */
|
||||||
board_invalTrayTiles( board, board->traySelBits[selPlayer] );
|
board_invalTrayTiles( board, board->traySelBits[selPlayer] );
|
||||||
|
|
||||||
|
ds->dtype = DT_TILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +140,6 @@ dragDropStart( BoardCtxt* board, BoardObjectType obj, XP_U16 x, XP_U16 y )
|
||||||
if ( result ) {
|
if ( result ) {
|
||||||
ds->cur = ds->start;
|
ds->cur = ds->start;
|
||||||
invalDragObj( board, &ds->start );
|
invalDragObj( board, &ds->start );
|
||||||
ds->dragInProgress = XP_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -159,9 +183,26 @@ dragDropEnd( BoardCtxt* board, XP_U16 xx, XP_U16 yy, XP_Bool* dragged )
|
||||||
/* If we've dropped on something, put the tile there! Since we
|
/* If we've dropped on something, put the tile there! Since we
|
||||||
don't remove it from its earlier location until it's dropped,
|
don't remove it from its earlier location until it's dropped,
|
||||||
we need to specify where it's coming from. */
|
we need to specify where it's coming from. */
|
||||||
if ( ds->dividerOnly ) {
|
if ( ds->dtype == DT_DIVIDER ) {
|
||||||
board->dividerInvalid = XP_TRUE;
|
board->dividerInvalid = XP_TRUE;
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
|
} else if ( ds->dtype == DT_HINTRGN ) {
|
||||||
|
if ( OBJ_BOARD == newObj && ds->didMove ) {
|
||||||
|
XP_Bool makeActive = ds->start.u.board.row <= ds->cur.u.board.row;
|
||||||
|
board->hasHintRect[board->selPlayer] = makeActive;
|
||||||
|
if ( makeActive ) {
|
||||||
|
setLimitsFrom( board, &board->limits[board->selPlayer] );
|
||||||
|
} else {
|
||||||
|
invalHintRectDiffs( board, &ds->cur, NULL );
|
||||||
|
}
|
||||||
|
board_resetEngine( board );
|
||||||
|
} else {
|
||||||
|
/* return it to whatever it was */
|
||||||
|
invalHintRectDiffs( board, &ds->cur, NULL );
|
||||||
|
invalCurHintRect( board, board->selPlayer );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
XP_U16 mod_startc, mod_startr;
|
XP_U16 mod_startc, mod_startr;
|
||||||
|
|
||||||
|
@ -208,7 +249,7 @@ dragDropEnd( BoardCtxt* board, XP_U16 xx, XP_U16 yy, XP_Bool* dragged )
|
||||||
invalDragObj( board, &ds->cur );
|
invalDragObj( board, &ds->cur );
|
||||||
invalDragObj( board, &ds->start );
|
invalDragObj( board, &ds->start );
|
||||||
}
|
}
|
||||||
ds->dragInProgress = XP_FALSE;
|
ds->dtype = DT_NONE;
|
||||||
|
|
||||||
return XP_TRUE;
|
return XP_TRUE;
|
||||||
} /* dragDropEnd */
|
} /* dragDropEnd */
|
||||||
|
@ -217,7 +258,7 @@ XP_Bool
|
||||||
dragDropGetBoardTile( const BoardCtxt* board, XP_U16* col, XP_U16* row )
|
dragDropGetBoardTile( const BoardCtxt* board, XP_U16* col, XP_U16* row )
|
||||||
{
|
{
|
||||||
const DragState* ds = &board->dragState;
|
const DragState* ds = &board->dragState;
|
||||||
XP_Bool found = !ds->dividerOnly && ds->cur.obj == OBJ_BOARD;
|
XP_Bool found = ds->dtype == DT_TILE && ds->cur.obj == OBJ_BOARD;
|
||||||
if ( found ) {
|
if ( found ) {
|
||||||
*col = ds->cur.u.board.col;
|
*col = ds->cur.u.board.col;
|
||||||
*row = ds->cur.u.board.row;
|
*row = ds->cur.u.board.row;
|
||||||
|
@ -230,8 +271,7 @@ dragDropIsBeingDragged( const BoardCtxt* board, XP_U16 col, XP_U16 row,
|
||||||
XP_Bool* isOrigin )
|
XP_Bool* isOrigin )
|
||||||
{
|
{
|
||||||
const DragState* ds = &board->dragState;
|
const DragState* ds = &board->dragState;
|
||||||
XP_Bool result = dragDropInProgress( board ) && !ds->dividerOnly
|
XP_Bool result = ds->dtype == DT_TILE && ds->cur.obj == OBJ_BOARD;
|
||||||
&& ds->cur.obj == OBJ_BOARD;
|
|
||||||
if ( result ) {
|
if ( result ) {
|
||||||
const DragState* ds = &board->dragState;
|
const DragState* ds = &board->dragState;
|
||||||
if ( (ds->cur.obj == OBJ_BOARD) && (ds->cur.u.board.col == col)
|
if ( (ds->cur.obj == OBJ_BOARD) && (ds->cur.u.board.col == col)
|
||||||
|
@ -255,7 +295,7 @@ dragDropGetTrayChanges( const BoardCtxt* board, XP_U16* rmvdIndx,
|
||||||
{
|
{
|
||||||
const DragState* ds = &board->dragState;
|
const DragState* ds = &board->dragState;
|
||||||
*addedIndx = *rmvdIndx = MAX_TRAY_TILES; /* too big means ignore me */
|
*addedIndx = *rmvdIndx = MAX_TRAY_TILES; /* too big means ignore me */
|
||||||
if ( dragDropInProgress( board ) && !ds->dividerOnly ) {
|
if ( ds->dtype == DT_TILE ) {
|
||||||
if ( OBJ_TRAY == ds->start.obj ) {
|
if ( OBJ_TRAY == ds->start.obj ) {
|
||||||
*rmvdIndx = ds->start.u.tray.index;
|
*rmvdIndx = ds->start.u.tray.index;
|
||||||
}
|
}
|
||||||
|
@ -265,10 +305,20 @@ dragDropGetTrayChanges( const BoardCtxt* board, XP_U16* rmvdIndx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XP_Bool
|
||||||
|
dragDropGetHintLimits( const BoardCtxt* board, BdHintLimits* limits )
|
||||||
|
{
|
||||||
|
XP_Bool result = board->dragState.dtype == DT_HINTRGN;
|
||||||
|
if ( result ) {
|
||||||
|
setLimitsFrom( board, limits );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
XP_Bool
|
XP_Bool
|
||||||
dragDropIsDividerDrag( const BoardCtxt* board )
|
dragDropIsDividerDrag( const BoardCtxt* board )
|
||||||
{
|
{
|
||||||
return dragDropInProgress( board ) && board->dragState.dividerOnly;
|
return board->dragState.dtype == DT_DIVIDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -276,12 +326,44 @@ dragDropTileInfo( const BoardCtxt* board, Tile* tile, XP_Bool* isBlank )
|
||||||
{
|
{
|
||||||
const DragState* ds = &board->dragState;
|
const DragState* ds = &board->dragState;
|
||||||
XP_ASSERT( dragDropInProgress( board ) );
|
XP_ASSERT( dragDropInProgress( board ) );
|
||||||
XP_ASSERT( !ds->dividerOnly );
|
XP_ASSERT( ds->dtype == DT_TILE );
|
||||||
XP_ASSERT ( OBJ_BOARD == ds->start.obj || OBJ_TRAY == ds->start.obj );
|
XP_ASSERT ( OBJ_BOARD == ds->start.obj || OBJ_TRAY == ds->start.obj );
|
||||||
*tile = ds->tile;
|
*tile = ds->tile;
|
||||||
*isBlank = ds->isBlank;
|
*isBlank = ds->isBlank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
invalHintRectDiffs( BoardCtxt* board, const DragObjInfo* cur,
|
||||||
|
const DragObjInfo* nxt )
|
||||||
|
{
|
||||||
|
XP_U16 startCol = board->dragState.start.u.board.col;
|
||||||
|
XP_U16 startRow = board->dragState.start.u.board.row;
|
||||||
|
|
||||||
|
/* These two regions will generally have close to 50% of their borders in
|
||||||
|
common. Try not to inval what needn't be inval'd. But at the moment
|
||||||
|
performance seems good enough without adding the complexity and new
|
||||||
|
bugs...
|
||||||
|
|
||||||
|
The challenge in doing a smarter diff is that some squares need to be
|
||||||
|
invalidated even if they're part of the borders of both limits rects,
|
||||||
|
in particular if one is a corner of one and just a side of another.
|
||||||
|
One simple but expensive way of accounting for this would be to call
|
||||||
|
figureHintAtts() on each square in the borders of both rects and
|
||||||
|
invalidate when the hintAttributes aren't the same for both. That
|
||||||
|
misses an opportunity to avoid doing any calculations on those border
|
||||||
|
squares that clearly haven't changed at all.
|
||||||
|
*/
|
||||||
|
|
||||||
|
invalCellRegion( board, startCol, startRow, cur->u.board.col,
|
||||||
|
cur->u.board.row );
|
||||||
|
if ( !!nxt ) {
|
||||||
|
BdHintLimits limits;
|
||||||
|
setLimitsFrom( board, &limits );
|
||||||
|
invalCellRegion( board, startCol, startRow, nxt->u.board.col,
|
||||||
|
nxt->u.board.row );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
||||||
BoardObjectType* onWhichP )
|
BoardObjectType* onWhichP )
|
||||||
|
@ -289,13 +371,14 @@ dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
||||||
XP_Bool moving = XP_FALSE;
|
XP_Bool moving = XP_FALSE;
|
||||||
DragObjInfo newInfo;
|
DragObjInfo newInfo;
|
||||||
DragState* ds = &board->dragState;
|
DragState* ds = &board->dragState;
|
||||||
|
XP_Bool doMore = XP_FALSE;
|
||||||
|
|
||||||
if ( !pointOnSomething( board, xx, yy, &newInfo.obj ) ) {
|
if ( !pointOnSomething( board, xx, yy, &newInfo.obj ) ) {
|
||||||
newInfo.obj = OBJ_NONE;
|
newInfo.obj = OBJ_NONE;
|
||||||
}
|
}
|
||||||
*onWhichP = newInfo.obj;
|
*onWhichP = newInfo.obj;
|
||||||
|
|
||||||
if ( ds->dividerOnly ) {
|
if ( ds->dtype == DT_DIVIDER ) {
|
||||||
if ( OBJ_TRAY == newInfo.obj ) {
|
if ( OBJ_TRAY == newInfo.obj ) {
|
||||||
XP_U16 newloc;
|
XP_U16 newloc;
|
||||||
XP_U16 scale = board->trayScaleH;
|
XP_U16 scale = board->trayScaleH;
|
||||||
|
@ -307,39 +390,78 @@ dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
|
||||||
moving = dividerMoved( board, newloc );
|
moving = dividerMoved( board, newloc );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( newInfo.obj == OBJ_BOARD ) {
|
/* If scrolling is possible, we can't trust pointOnSomething. So
|
||||||
(void)coordToCell( board, xx, yy, &newInfo.u.board.col,
|
check coordToCell. */
|
||||||
&newInfo.u.board.row );
|
if( coordToCell( board, xx, yy, &newInfo.u.board.col,
|
||||||
moving = (OBJ_TRAY == ds->cur.obj)
|
&newInfo.u.board.row ) ) {
|
||||||
|| (newInfo.u.board.col != ds->cur.u.board.col)
|
newInfo.obj = OBJ_BOARD;
|
||||||
|| (newInfo.u.board.row != ds->cur.u.board.row);
|
doMore = XP_TRUE;
|
||||||
} else if ( newInfo.obj == OBJ_TRAY ) {
|
} else {
|
||||||
XP_Bool onDivider;
|
doMore = OBJ_TRAY == newInfo.obj;
|
||||||
XP_S16 index = pointToTileIndex( board, xx, yy, &onDivider );
|
}
|
||||||
if ( !onDivider ) {
|
}
|
||||||
if ( index < 0 ) { /* negative means onto empty part of tray.
|
|
||||||
Force left. */
|
if ( doMore ) {
|
||||||
index = model_getNumTilesInTray( board->model,
|
#ifdef XWFEATURE_SEARCHLIMIT
|
||||||
board->selPlayer );
|
if ( ds->dtype == DT_HINTRGN && newInfo.obj != OBJ_BOARD ) {
|
||||||
if ( OBJ_TRAY == ds->start.obj ) {
|
/* do nothing */
|
||||||
--index; /* dragging right into space */
|
#endif
|
||||||
|
} else {
|
||||||
|
if ( newInfo.obj == OBJ_BOARD ) {
|
||||||
|
(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);
|
||||||
|
|
||||||
|
} 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. */
|
||||||
|
index = model_getNumTilesInTray( board->model,
|
||||||
|
board->selPlayer );
|
||||||
|
if ( OBJ_TRAY == ds->start.obj ) {
|
||||||
|
--index; /* dragging right into space */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
moving = (OBJ_BOARD == ds->cur.obj)
|
||||||
|
|| (index != ds->cur.u.tray.index);
|
||||||
|
if ( moving ) {
|
||||||
|
newInfo.u.tray.index = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
moving = (OBJ_BOARD == ds->cur.obj)
|
|
||||||
|| (index != ds->cur.u.tray.index);
|
|
||||||
if ( moving ) {
|
|
||||||
newInfo.u.tray.index = index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( moving ) {
|
if ( moving ) {
|
||||||
invalDragObjRange( board, &ds->cur, &newInfo );
|
if ( ds->dtype == DT_TILE ) {
|
||||||
XP_MEMCPY( &ds->cur, &newInfo, sizeof(ds->cur) );
|
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 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
XP_MEMCPY( &ds->cur, &newInfo, sizeof(ds->cur) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( moving ) {
|
if ( moving ) {
|
||||||
|
if ( !ds->didMove ) {
|
||||||
|
/* This is the first time we've moved!!! Kill any future timers,
|
||||||
|
and if there's a window up kill it.*/
|
||||||
|
board->penTimerFired = XP_FALSE;
|
||||||
|
if ( valHintMiniWindowActive( board ) ) {
|
||||||
|
hideMiniWindow( board, XP_TRUE, MINIWINDOW_VALHINT );
|
||||||
|
}
|
||||||
|
}
|
||||||
ds->didMove = XP_TRUE;
|
ds->didMove = XP_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +487,16 @@ invalDragObjRange( BoardCtxt* board, const DragObjInfo* from,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setLimitsFrom( const BoardCtxt* board, BdHintLimits* limits )
|
||||||
|
{
|
||||||
|
const DragState* ds = &board->dragState;
|
||||||
|
limits->left = XP_MIN( ds->start.u.board.col, ds->cur.u.board.col );
|
||||||
|
limits->right = XP_MAX( ds->start.u.board.col, ds->cur.u.board.col );
|
||||||
|
limits->top = XP_MIN( ds->start.u.board.row, ds->cur.u.board.row );
|
||||||
|
limits->bottom = XP_MAX( ds->start.u.board.row, ds->cur.u.board.row );
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CPLUS
|
#ifdef CPLUS
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,14 +29,13 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
XP_Bool dragDropInProgress( const BoardCtxt* board );
|
XP_Bool dragDropInProgress( const BoardCtxt* board );
|
||||||
|
XP_Bool dragDropHasMoved( const BoardCtxt* board );
|
||||||
|
|
||||||
/* dragDropStart
|
|
||||||
* Pass col,row for board, but raw x,y for tray. Yeah, sucks.
|
|
||||||
*/
|
|
||||||
XP_Bool dragDropStart( BoardCtxt* board, BoardObjectType obj,
|
XP_Bool dragDropStart( BoardCtxt* board, BoardObjectType obj,
|
||||||
XP_U16 x, XP_U16 y );
|
XP_U16 xx, XP_U16 yy );
|
||||||
XP_Bool dragDropContinue( BoardCtxt* board, XP_U16 x, XP_U16 y );
|
XP_Bool dragDropContinue( BoardCtxt* board, XP_U16 xx, XP_U16 yy );
|
||||||
XP_Bool dragDropEnd( BoardCtxt* board, XP_U16 x, XP_U16 y, XP_Bool* dragged );
|
XP_Bool dragDropEnd( BoardCtxt* board, XP_U16 xx, XP_U16 yy, XP_Bool* dragged );
|
||||||
|
|
||||||
XP_Bool dragDropGetBoardTile( const BoardCtxt* board, XP_U16* col, XP_U16* row );
|
XP_Bool dragDropGetBoardTile( const BoardCtxt* board, XP_U16* col, XP_U16* row );
|
||||||
XP_Bool dragDropIsBeingDragged( const BoardCtxt* board, XP_U16 col, XP_U16 row,
|
XP_Bool dragDropIsBeingDragged( const BoardCtxt* board, XP_U16 col, XP_U16 row,
|
||||||
XP_Bool* isOrigin );
|
XP_Bool* isOrigin );
|
||||||
|
@ -47,6 +46,7 @@ XP_Bool dragDropIsBeingDragged( const BoardCtxt* board, XP_U16 col, XP_U16 row,
|
||||||
*/
|
*/
|
||||||
void dragDropGetTrayChanges( const BoardCtxt* board, XP_U16* rmvdIndx,
|
void dragDropGetTrayChanges( const BoardCtxt* board, XP_U16* rmvdIndx,
|
||||||
XP_U16* addedIndx );
|
XP_U16* addedIndx );
|
||||||
|
XP_Bool dragDropGetHintLimits( const BoardCtxt* board, BdHintLimits* limits );
|
||||||
XP_Bool dragDropIsDividerDrag( const BoardCtxt* board );
|
XP_Bool dragDropIsDividerDrag( const BoardCtxt* board );
|
||||||
|
|
||||||
void dragDropTileInfo( const BoardCtxt* board, Tile* tile, XP_Bool* isBlank );
|
void dragDropTileInfo( const BoardCtxt* board, Tile* tile, XP_Bool* isBlank );
|
||||||
|
|
Loading…
Reference in a new issue