Tweak scroll-of-focussed-board inval code so we don't inval the whole

board, which looks crappy.  Instead inval only what was previously a
border row, and pass a new param to draw_vertScrollBoard so the
platform can choose not to scroll cells that will just get overwritten
with different bits.
This commit is contained in:
ehouse 2007-01-21 22:59:29 +00:00
parent 73bc1925fd
commit 17993fea06
6 changed files with 91 additions and 37 deletions

View file

@ -892,7 +892,31 @@ board_invalAllTiles( BoardCtxt* board )
#ifdef KEYBOARD_NAV
#ifdef PERIMETER_FOCUS
static void
board_invalPerimeter( BoardCtxt* board )
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;
XP_U16 firstRow, lastRow;
XP_ASSERT( diff != 0 );
if ( diff < 0 ) {
/* moving up; inval row previously on bottom */
firstRow = board->yOffset + 1;
lastRow = board->prevYScrollOffset;
} else {
XP_U16 nVisible = board->lastVisibleRow - board->yOffset;
lastRow = board->prevYScrollOffset + nVisible - 1;
firstRow = lastRow - diff + 1;
}
XP_ASSERT( firstRow <= lastRow );
while ( firstRow <= lastRow ) {
board->redrawFlags[firstRow] |= ~0;
++firstRow;
}
} /* invalOldPerimeter */
static void
invalPerimeter( BoardCtxt* board )
{
XP_U16 lastCol = model_numCols( board->model ) - 1;
XP_U16 firstAndLast = (1 << lastCol) | 1;
@ -906,7 +930,7 @@ board_invalPerimeter( BoardCtxt* board )
while ( --lastRow > firstRow ) {
board->redrawFlags[lastRow] |= firstAndLast;
}
}
} /* invalPerimeter */
#endif
#endif
@ -1062,32 +1086,29 @@ static void
scrollIfCan( BoardCtxt* board )
{
if ( board->yOffset != board->prevYScrollOffset ) {
if ( board->focussed == OBJ_BOARD && !board->focusHasDived ) {
/* an edge case. Just brute force it. */
board_invalAllTiles( board );
XP_Rect scrollR = board->boardBounds;
XP_Bool scrolled;
XP_S16 dist;
#ifdef PERIMETER_FOCUS
if ( (board->focussed == OBJ_BOARD) && !board->focusHasDived ) {
invalOldPerimeter( board );
}
#endif
invalSelTradeWindow( board );
dist = (board->yOffset - board->prevYScrollOffset)
* board->boardVScale;
scrolled = draw_vertScrollBoard( board->draw, &scrollR, dist,
dfsFor( board, OBJ_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.... */
invalCellsUnderRect( board, &scrollR );
} else {
XP_Rect scrollR = board->boardBounds;
XP_Bool scrolled;
XP_S16 dist;
/* If there's a focus-rect drawn on the board, we need to inval any
row of it that's going to get scrolled into the center since it
needs to be redrawn without the border. */
invalSelTradeWindow( board );
dist = (board->yOffset - board->prevYScrollOffset)
* board->boardVScale;
scrolled = draw_vertScrollBoard( board->draw, &scrollR, dist );
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.... */
invalCellsUnderRect( board, &scrollR );
} else {
board_invalAll( board );
}
board_invalAll( board );
}
board->prevYScrollOffset = board->yOffset;
}
@ -2808,7 +2829,7 @@ invalFocusOwner( BoardCtxt* board )
invalCell( board, loc.col, loc.row );
} else {
#ifdef PERIMETER_FOCUS
board_invalPerimeter( board );
invalPerimeter( board );
#else
board_invalAllTiles( board );
#endif

View file

@ -114,7 +114,7 @@ typedef struct DrawCtxVTable {
/* rect is not const: set by callee */
XP_Bool DRAW_VTABLE_NAME(vertScrollBoard) (DrawCtx* dctx, XP_Rect* rect,
XP_S16 dist );
XP_S16 dist, DrawFocusState dfs );
XP_Bool DRAW_VTABLE_NAME(trayBegin) ( DrawCtx* dctx, const XP_Rect* rect,
XP_U16 owner,
@ -229,8 +229,8 @@ struct DrawCtx {
#define draw_boardBegin( dc,d,r,f ) CALL_DRAW_NAME3(boardBegin, dc, d,r,f)
#define draw_objFinished( dc, t, r, d ) CALL_DRAW_NAME3(objFinished, (dc), (t), (r), (d))
#define draw_trayBegin( dc, r, o, f ) CALL_DRAW_NAME3(trayBegin,dc, r, o, f)
#define draw_vertScrollBoard( dc, r, d ) \
CALL_DRAW_NAME2(vertScrollBoard, (dc),(r),(d))
#define draw_vertScrollBoard( dc, r, d, f ) \
CALL_DRAW_NAME3(vertScrollBoard, (dc),(r),(d),(f))
#define draw_scoreBegin( dc, r, t, f ) \
CALL_DRAW_NAME3( scoreBegin,(dc), (r), (t), (f))
#define draw_measureRemText( dc, r, n, wp, hp ) \

View file

@ -288,6 +288,27 @@ gtk_draw_objFinished( DrawCtx* XP_UNUSED(p_dctx),
{
} /* draw_finished */
static XP_Bool
gtk_draw_vertScrollBoard( DrawCtx* XP_UNUSED(p_dctx), XP_Rect* XP_UNUSED(rect),
XP_S16 XP_UNUSED(dist),
DrawFocusState XP_UNUSED(dfs) )
{
/* Turn this on to mimic what palm does, but need to figure out some gtk
analog to copybits for it to actually work. */
#if 0
XP_Bool up = dist < 0;
if ( up ) {
dist *= -1;
} else {
rect->top += rect->height - dist;
}
rect->height = dist;
#endif
return XP_TRUE;
}
static void
drawHintBorders( GtkDrawCtx* dctx, const XP_Rect* rect, HintAtts hintAtts)
{
@ -967,7 +988,7 @@ gtkDrawCtxtMake( GtkWidget* drawing_area, GtkAppGlobals* globals )
SET_VTABLE_ENTRY( dctx->vtable, draw_drawCell, gtk );
SET_VTABLE_ENTRY( dctx->vtable, draw_invertCell, gtk );
SET_VTABLE_ENTRY( dctx->vtable, draw_objFinished, gtk );
SET_VTABLE_ENTRY( dctx->vtable, draw_vertScrollBoard, gtk );
SET_VTABLE_ENTRY( dctx->vtable, draw_trayBegin, gtk );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawTile, gtk );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawTileBack, gtk );

View file

@ -96,6 +96,7 @@ extern void linux_debugf(char*, ...);
#define XP_MIN(a,b) ((a)<(b)?(a):(b))
#define XP_MAX(a,b) ((a)>(b)?(a):(b))
#define XP_ABS(a) ((a)>=0?(a):-(a))
#ifdef DEBUG
# define XP_ASSERT(b) assert(b)

View file

@ -46,6 +46,7 @@
#define DRAW_FOCUS_FRAME 1
#ifdef DRAW_FOCUS_FRAME
# define TREAT_AS_CURSOR(d,f) ((((f) & CELL_ISCURSOR) != 0) && !(d)->topFocus )
# define FOCUS_BORDER_WIDTH 6
#else
# define TREAT_AS_CURSOR(d,f) (((f) & CELL_ISCURSOR) != 0)
#endif
@ -300,7 +301,8 @@ palm_draw_objFinished( DrawCtx* p_dctx, BoardObjectType typ,
r.width = rect->width - 1;
r.height = rect->height - 1;
for ( i = 0; i < 6; ++i ) {
for ( i = dctx->doHiRes?FOCUS_BORDER_WIDTH:FOCUS_BORDER_WIDTH/2;
i > 0; --i ) {
insetRect( &r, 1 );
WinDrawRectangleFrame(rectangleFrame, (RectangleType*)&r );
}
@ -836,7 +838,7 @@ palm_clr_draw_drawBoardArrow( DrawCtx* p_dctx, const XP_Rect* rectP,
static void
palm_draw_scoreBegin( DrawCtx* p_dctx, const XP_Rect* rect,
XP_U16 XP_UNUSED(numPlayers),
DrawFocusState dfs )
DrawFocusState XP_UNUSED(dfs) )
{
PalmDrawCtx* dctx = (PalmDrawCtx*)p_dctx;
@ -862,7 +864,7 @@ rectContainsRect( const XP_Rect* rect1, const XP_Rect* rect2 )
static XP_Bool
palm_draw_vertScrollBoard( DrawCtx* XP_UNUSED(p_dctx), XP_Rect* rect,
XP_S16 dist )
XP_S16 dist, DrawFocusState dfs )
{
RectangleType clip;
XP_Bool canDoIt;
@ -883,6 +885,15 @@ palm_draw_vertScrollBoard( DrawCtx* XP_UNUSED(p_dctx), XP_Rect* rect,
dist = -dist;
}
#ifdef PERIMETER_FOCUS
if ( dfs == DFS_TOP ) {
rect->height -= FOCUS_BORDER_WIDTH;
if ( dir == winDown ) {
rect->top += FOCUS_BORDER_WIDTH;
}
}
#endif
WinScrollRectangle( (RectangleType*)rect, dir, dist, &vacated );
*rect = *(XP_Rect*)&vacated;
}
@ -1337,7 +1348,7 @@ palm_draw_measureMiniWText( DrawCtx* p_dctx, const XP_UCHAR* str,
}
*widthP = maxWidth;
*heightP = height + 3;
*heightP = height + 4;
HIGHRES_POP_LOC( (PalmDrawCtx*)p_dctx );
} /* palm_draw_measureMiniWText */

View file

@ -958,7 +958,7 @@ DRAW_FUNC_NAME(destroyCtxt)( DrawCtx* p_dctx )
#ifdef DRAW_LINK_DIRECT
DLSTATIC XP_Bool
DRAW_FUNC_NAME(vertScrollBoard)( DrawCtx* p_dctx, XP_Rect* rect,
XP_S16 dist )
XP_S16 dist, DrawFocusState XP_UNUSED(dfs) )
{
XP_Bool success = XP_FALSE;
/* board passes in the whole board rect, so we need to subtract from it