From 17993fea0670c519eccd8ef918d3c45d072c6c87 Mon Sep 17 00:00:00 2001 From: ehouse Date: Sun, 21 Jan 2007 22:59:29 +0000 Subject: [PATCH] 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. --- common/board.c | 77 +++++++++++++++++++++++++++++++------------------ common/draw.h | 6 ++-- linux/gtkdraw.c | 23 ++++++++++++++- linux/xptypes.h | 1 + palm/palmdraw.c | 19 +++++++++--- wince/cedraw.c | 2 +- 6 files changed, 91 insertions(+), 37 deletions(-) diff --git a/common/board.c b/common/board.c index 171a001ed..55edf0d79 100644 --- a/common/board.c +++ b/common/board.c @@ -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 diff --git a/common/draw.h b/common/draw.h index b75efa4d2..6badc39cd 100644 --- a/common/draw.h +++ b/common/draw.h @@ -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 ) \ diff --git a/linux/gtkdraw.c b/linux/gtkdraw.c index 4c096c2ec..02c72775c 100644 --- a/linux/gtkdraw.c +++ b/linux/gtkdraw.c @@ -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 ); diff --git a/linux/xptypes.h b/linux/xptypes.h index d307e6f37..c8397a0a3 100644 --- a/linux/xptypes.h +++ b/linux/xptypes.h @@ -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) diff --git a/palm/palmdraw.c b/palm/palmdraw.c index d8c7db155..397a7ee7b 100644 --- a/palm/palmdraw.c +++ b/palm/palmdraw.c @@ -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 */ diff --git a/wince/cedraw.c b/wince/cedraw.c index 39dabc564..3c3f6e2cb 100755 --- a/wince/cedraw.c +++ b/wince/cedraw.c @@ -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