diff --git a/xwords4/common/draw.h b/xwords4/common/draw.h index 965a7990f..a7eb6026a 100644 --- a/xwords4/common/draw.h +++ b/xwords4/common/draw.h @@ -180,7 +180,7 @@ typedef struct DrawCtxVTable { void DRAW_VTABLE_NAME(drawTileBack) ( DrawCtx* dctx, const XP_Rect* rect, CellFlags flags ); void DRAW_VTABLE_NAME(drawTrayDivider) ( DrawCtx* dctx, const XP_Rect* rect, - XP_Bool selected ); + CellFlags flags ); void DRAW_VTABLE_NAME(clearRect) ( DrawCtx* dctx, const XP_Rect* rect ); diff --git a/xwords4/linux/cursesdraw.c b/xwords4/linux/cursesdraw.c index dfe6c6762..22b9ae917 100644 --- a/xwords4/linux/cursesdraw.c +++ b/xwords4/linux/cursesdraw.c @@ -428,7 +428,7 @@ curses_draw_drawTileBack( DrawCtx* p_dctx, const XP_Rect* rect, static void curses_draw_drawTrayDivider( DrawCtx* p_dctx, const XP_Rect* rect, - XP_Bool XP_UNUSED(selected) ) + CellFlags XP_UNUSED(flags) ) { CursesDrawCtx* dctx = (CursesDrawCtx*)p_dctx; wmove( dctx->boardWin, rect->top, rect->left ); diff --git a/xwords4/linux/gtkdraw.c b/xwords4/linux/gtkdraw.c index 7fcb5ab8b..6e44bebdc 100644 --- a/xwords4/linux/gtkdraw.c +++ b/xwords4/linux/gtkdraw.c @@ -316,31 +316,6 @@ gtk_draw_boardBegin( DrawCtx* p_dctx, const DictionaryCtxt* XP_UNUSED(dict), return XP_TRUE; } /* draw_finish */ -static void -drawFocusFrame( GtkDrawCtx* dctx, const XP_Rect* r ) -{ - XP_Rect rectInset = *r; - XP_U16 i; - XP_U16 targetDim; - - targetDim = XP_MIN( rectInset.width, rectInset.height ); - targetDim >>= 1; - - gdk_gc_set_foreground( dctx->drawGC, &dctx->black ); - - for ( i = 0; i < 5; ++i ) { - insetRect( &rectInset, 1 ); - if ( rectInset.width < targetDim || rectInset.height < targetDim ) { - break; - } - gdk_draw_rectangle( DRAW_WHAT(dctx), - dctx->drawGC, - FALSE, - rectInset.left, rectInset.top, - rectInset.width+1, rectInset.height+1 ); - } -} - static void gtk_draw_objFinished( DrawCtx* XP_UNUSED(p_dctx), BoardObjectType XP_UNUSED(typ), @@ -436,14 +411,15 @@ gtk_draw_drawCell( DrawCtx* p_dctx, const XP_Rect* rect, const XP_UCHAR* letter, XP_Rect rectInset = *rect; XP_Bool showGrid = dctx->globals->gridOn; XP_Bool highlight = (flags & CELL_HIGHLIGHT) != 0; + GdkColor* cursor = + ((flags & CELL_ISCURSOR) != 0) ? &dctx->cursor : NULL; gtkEraseRect( dctx, rect ); insetRect( &rectInset, 1 ); - gdk_gc_set_foreground( dctx->drawGC, &dctx->black ); - if ( showGrid ) { + gdk_gc_set_foreground( dctx->drawGC, &dctx->black ); gdk_draw_rectangle( DRAW_WHAT(dctx), dctx->drawGC, FALSE, @@ -454,27 +430,40 @@ gtk_draw_drawCell( DrawCtx* p_dctx, const XP_Rect* rect, const XP_UCHAR* letter, /* We draw just an empty, potentially colored, square IFF there's nothing in the cell or if CELL_DRAGSRC is set */ if ( (flags & (CELL_DRAGSRC|CELL_ISEMPTY)) != 0 ) { - if ( bonus != BONUS_NONE ) { - gdk_gc_set_foreground( dctx->drawGC, &dctx->bonusColors[bonus-1] ); - gdk_draw_rectangle( DRAW_WHAT(dctx), dctx->drawGC, TRUE, - rectInset.left, rectInset.top, - rectInset.width+1, rectInset.height+1 ); + if ( !!cursor || bonus != BONUS_NONE ) { + GdkColor* foreground; + if ( !!cursor ) { + foreground = cursor; + } else if ( bonus != BONUS_NONE ) { + foreground = &dctx->bonusColors[bonus-1]; + } else { + foreground = NULL; + } + if ( !!foreground ) { + gdk_gc_set_foreground( dctx->drawGC, foreground ); + gdk_draw_rectangle( DRAW_WHAT(dctx), dctx->drawGC, TRUE, + rectInset.left, rectInset.top, + rectInset.width+1, rectInset.height+1 ); + } } if ( (flags & CELL_ISSTAR) != 0 ) { draw_string_at( dctx, "*", rect->height, rect, XP_GTK_JUST_CENTER, &dctx->black, NULL ); } } else if ( !!letter ) { - GdkColor* foreground; - - if ( !highlight ) { + GdkColor* foreground = cursor; + if ( cursor ) { + gdk_gc_set_foreground( dctx->drawGC, cursor ); + } else if ( !highlight ) { gdk_gc_set_foreground( dctx->drawGC, &dctx->tileBack ); } gdk_draw_rectangle( DRAW_WHAT(dctx), dctx->drawGC, TRUE, rectInset.left, rectInset.top, rectInset.width+1, rectInset.height+1 ); - foreground = highlight? &dctx->white : &dctx->playerColors[owner]; + if ( !foreground ) { + foreground = highlight? &dctx->white : &dctx->playerColors[owner]; + } draw_string_at( dctx, letter, rectInset.height-2, &rectInset, XP_GTK_JUST_CENTER, foreground, NULL ); @@ -493,10 +482,6 @@ gtk_draw_drawCell( DrawCtx* p_dctx, const XP_Rect* rect, const XP_UCHAR* letter, drawHintBorders( dctx, rect, hintAtts ); - if ( (flags & CELL_ISCURSOR) != 0 ) { - drawFocusFrame( dctx, rect ); - } - return XP_TRUE; } /* gtk_draw_drawCell */ @@ -540,19 +525,21 @@ gtkDrawTileImpl( DrawCtx* p_dctx, const XP_Rect* rect, const XP_UCHAR* textP, gint len; GtkDrawCtx* dctx = (GtkDrawCtx*)p_dctx; XP_Rect insetR = *rect; + XP_Bool isCursor = (flags & CELL_ISCURSOR) != 0; if ( clearBack ) { gtkEraseRect( dctx, &insetR ); } - if ( val >= 0 ) { + if ( isCursor || (val >= 0) ) { GdkColor* foreground = &dctx->playerColors[dctx->trayOwner]; XP_Rect formatRect = insetR; insetRect( &insetR, 1 ); if ( clearBack ) { - gdk_gc_set_foreground( dctx->drawGC, &dctx->tileBack ); + gdk_gc_set_foreground( dctx->drawGC, + isCursor? &dctx->cursor:&dctx->tileBack ); gdk_draw_rectangle( DRAW_WHAT(dctx), dctx->drawGC, XP_TRUE, @@ -560,48 +547,45 @@ gtkDrawTileImpl( DrawCtx* p_dctx, const XP_Rect* rect, const XP_UCHAR* textP, insetR.height ); } - formatRect.left += 3; - formatRect.width -= 6; + if ( val >= 0 ) { + formatRect.left += 3; + formatRect.width -= 6; - if ( !!textP ) { - if ( *textP != LETTER_NONE ) { /* blank */ - draw_string_at( dctx, textP, formatRect.height>>1, - &formatRect, XP_GTK_JUST_TOPLEFT, - foreground, NULL ); + if ( !!textP ) { + if ( *textP != LETTER_NONE ) { /* blank */ + draw_string_at( dctx, textP, formatRect.height>>1, + &formatRect, XP_GTK_JUST_TOPLEFT, + foreground, NULL ); + } + } else if ( !!bitmap ) { + drawBitmapFromLBS( dctx, bitmap, &insetR ); } - } else if ( !!bitmap ) { - drawBitmapFromLBS( dctx, bitmap, &insetR ); - } - sprintf( numbuf, "%d", val ); - len = strlen( numbuf ); + sprintf( numbuf, "%d", val ); + len = strlen( numbuf ); - draw_string_at( dctx, numbuf, formatRect.height>>2, - &formatRect, XP_GTK_JUST_BOTTOMRIGHT, - foreground, NULL ); + draw_string_at( dctx, numbuf, formatRect.height>>2, + &formatRect, XP_GTK_JUST_BOTTOMRIGHT, + foreground, NULL ); - /* frame the tile */ - gdk_gc_set_foreground( dctx->drawGC, &dctx->black ); - gdk_draw_rectangle( DRAW_WHAT(dctx), - dctx->drawGC, - FALSE, - insetR.left, insetR.top, insetR.width, - insetR.height ); - - if ( (flags & CELL_HIGHLIGHT) != 0 ) { - insetRect( &insetR, 1 ); + /* frame the tile */ + gdk_gc_set_foreground( dctx->drawGC, &dctx->black ); gdk_draw_rectangle( DRAW_WHAT(dctx), dctx->drawGC, - FALSE, insetR.left, insetR.top, - insetR.width, insetR.height); + FALSE, + insetR.left, insetR.top, insetR.width, + insetR.height ); + + if ( (flags & CELL_HIGHLIGHT) != 0 ) { + insetRect( &insetR, 1 ); + gdk_draw_rectangle( DRAW_WHAT(dctx), + dctx->drawGC, + FALSE, insetR.left, insetR.top, + insetR.width, insetR.height); + } } } - - if ((flags & CELL_ISCURSOR) != 0 ) { - drawFocusFrame( dctx, rect ); - } - } /* gtkDrawTileImpl */ static void @@ -629,42 +613,49 @@ gtk_draw_drawTileBack( DrawCtx* p_dctx, const XP_Rect* rect, CellFlags flags ) { GtkDrawCtx* dctx = (GtkDrawCtx*)p_dctx; + XP_Bool hasCursor = (flags & CELL_ISCURSOR) != 0; XP_Rect r = *rect; insetRect( &r, 1 ); - gdk_gc_set_foreground( dctx->drawGC, + gdk_gc_set_foreground( dctx->drawGC, &dctx->playerColors[dctx->trayOwner] ); gdk_draw_rectangle( DRAW_WHAT(dctx), - dctx->drawGC, TRUE, + dctx->drawGC, TRUE, r.left, r.top, r.width, r.height ); insetRect( &r, 1 ); - gdk_gc_set_foreground( dctx->drawGC, &dctx->tileBack ); + gdk_gc_set_foreground( dctx->drawGC, + hasCursor? &dctx->cursor : &dctx->tileBack ); gdk_draw_rectangle( DRAW_WHAT(dctx), - dctx->drawGC, TRUE, + dctx->drawGC, TRUE, r.left, r.top, r.width, r.height ); draw_string_at( dctx, "?", r.height, &r, XP_GTK_JUST_CENTER, &dctx->playerColors[dctx->trayOwner], NULL ); - if ( (flags & CELL_ISCURSOR) != 0 ) { - drawFocusFrame( dctx, rect ); - } } /* gtk_draw_drawTileBack */ static void gtk_draw_drawTrayDivider( DrawCtx* p_dctx, const XP_Rect* rect, - XP_Bool selected ) + CellFlags flags ) { GtkDrawCtx* dctx = (GtkDrawCtx*)p_dctx; XP_Rect r = *rect; + XP_Bool selected = 0 != (flags & CELL_HIGHLIGHT); + XP_Bool isCursor = 0 != (flags & CELL_ISCURSOR); gtkEraseRect( dctx, &r ); - ++r.left; - r.width -= selected? 2:1; + gdk_gc_set_foreground( dctx->drawGC, + isCursor? &dctx->cursor:&dctx->white ); + gdk_draw_rectangle( DRAW_WHAT(dctx), + dctx->drawGC, XP_TRUE, + r.left, r.top, r.width, r.height ); + + r.left += 2; + r.width -= 4; if ( selected ) { --r.height; } @@ -852,9 +843,19 @@ gtk_draw_score_drawPlayer( DrawCtx* p_dctx, const XP_Rect* rInner, { GtkDrawCtx* dctx = (GtkDrawCtx*)p_dctx; char scoreBuf[20]; + XP_Bool hasCursor = (dsi->flags & CELL_ISCURSOR) != 0; + GdkColor* cursor = NULL; formatScoreText( scoreBuf, sizeof(scoreBuf), dsi ); + if ( hasCursor ) { + cursor = &dctx->cursor; + gdk_gc_set_foreground( dctx->drawGC, cursor ); + gdk_draw_rectangle( DRAW_WHAT(dctx), dctx->drawGC, + TRUE, rOuter->left, rOuter->top, + rOuter->width, rOuter->height ); + } + gdk_gc_set_foreground( dctx->drawGC, &dctx->playerColors[dsi->playerNum] ); if ( dsi->selected ) { @@ -866,11 +867,8 @@ gtk_draw_score_drawPlayer( DrawCtx* p_dctx, const XP_Rect* rInner, draw_string_at( dctx, scoreBuf, rInner->height - 1, rInner, XP_GTK_JUST_CENTER, - &dctx->playerColors[dsi->playerNum], NULL ); + &dctx->playerColors[dsi->playerNum], cursor ); - if ( ((dsi->flags & CELL_ISCURSOR) != 0) ) { - drawFocusFrame( dctx, rOuter ); - } } /* gtk_draw_score_drawPlayer */ static void @@ -882,6 +880,8 @@ gtk_draw_score_pendingScore( DrawCtx* p_dctx, const XP_Rect* rect, char buf[5]; XP_U16 ht; XP_Rect localR; + GdkColor* cursor = ((flags & CELL_ISCURSOR) != 0) + ? &dctx->cursor : NULL; if ( score >= 0 ) { sprintf( buf, "%.3d", score ); @@ -898,14 +898,11 @@ gtk_draw_score_pendingScore( DrawCtx* p_dctx, const XP_Rect* rect, ht = localR.height >> 2; draw_string_at( dctx, "Pts:", ht, &localR, XP_GTK_JUST_TOPLEFT, - &dctx->black, NULL ); + &dctx->black, cursor ); draw_string_at( dctx, buf, ht, &localR, XP_GTK_JUST_BOTTOMRIGHT, - &dctx->black, NULL ); + &dctx->black, cursor ); - if ( !dctx->topFocus && (flags & CELL_ISCURSOR) != 0 ) { - drawFocusFrame( dctx, rect ); - } } /* gtk_draw_score_pendingScore */ static void @@ -1137,6 +1134,7 @@ gtkDrawCtxtMake( GtkWidget* drawing_area, GtkAppGlobals* globals ) allocAndSet( map, &dctx->playerColors[3], 0xAFFF, 0x0000, 0xAFFF ); allocAndSet( map, &dctx->tileBack, 0xFFFF, 0xFFFF, 0x9999 ); + allocAndSet( map, &dctx->cursor, 0x7FFF, 0x7FFF, 0xFFFF ); allocAndSet( map, &dctx->red, 0xFFFF, 0x0000, 0x0000 ); return (DrawCtx*)dctx; diff --git a/xwords4/linux/gtkmain.h b/xwords4/linux/gtkmain.h index 1178802f2..ff47c1cb5 100644 --- a/xwords4/linux/gtkmain.h +++ b/xwords4/linux/gtkmain.h @@ -49,6 +49,7 @@ typedef struct GtkDrawCtx { GdkColor white; GdkColor red; /* for pending tiles */ GdkColor tileBack; /* for pending tiles */ + GdkColor cursor; GdkColor bonusColors[4]; GdkColor playerColors[MAX_NUM_PLAYERS]; diff --git a/xwords4/palm/palmdraw.c b/xwords4/palm/palmdraw.c index f178a2747..25662e6b3 100644 --- a/xwords4/palm/palmdraw.c +++ b/xwords4/palm/palmdraw.c @@ -96,10 +96,10 @@ static void doDrawPlayer( PalmDrawCtx* dctx, const DrawScoreInfo* dsi, } static void -eraseRect( /* PalmDrawCtx* dctx, */const XP_Rect* rect ) +pmEraseRect( /* PalmDrawCtx* dctx, */const XP_Rect* rect ) { WinEraseRectangle( (const RectangleType*)rect, 0 ); -} /* eraseRect */ +} /* pmEraseRect */ static void insetRect2( XP_Rect* rect, XP_S16 byX, XP_S16 byY ) @@ -378,7 +378,7 @@ palm_clr_draw_score_drawPlayer( DrawCtx* p_dctx, const XP_Rect* rInner, if ( dsi->flags && CELL_ISCURSOR ) { WinSetBackColor( dctx->drawingPrefs->drawColors[COLOR_CURSOR] ); - eraseRect( rOuter ); + pmEraseRect( rOuter ); } if ( dsi->selected ) { @@ -386,7 +386,7 @@ palm_clr_draw_score_drawPlayer( DrawCtx* p_dctx, const XP_Rect* rInner, insetRect2( &r, (r.width - rOuter->width) >> 2, (r.height - rOuter->height) >> 2 ); WinSetBackColor( dctx->drawingPrefs->drawColors[COLOR_BLACK] ); - eraseRect( &r ); + pmEraseRect( &r ); txtIndex = COLOR_WHITE; } else { txtIndex = COLOR_PLAYER1+playerNum; @@ -494,7 +494,7 @@ palm_common_draw_drawCell( DrawCtx* p_dctx, const XP_Rect* rect, insetRect( &localR, 1 ); } - eraseRect( &localR ); + pmEraseRect( &localR ); if ( showEmpty ) { /* do nothing */ @@ -690,16 +690,11 @@ palm_draw_drawTile( DrawCtx* p_dctx, const XP_Rect* rect, localR.width -= 3 * doubler; localR.left += 2 * doubler; - if ( cursor && !dctx->topFocus ) { + if ( (cursor && !dctx->topFocus) || (!empty && !cursor) ) { /* this will fill it with the tile background color */ WinEraseRectangle( (const RectangleType*)&localR, 0 ); } - /* this will fill it with the tile background color */ - if ( !empty && !cursor ) { - WinEraseRectangle( (const RectangleType*)&localR, 0 ); - } - if ( !empty ) { /* Draw the number before the letter. Some PalmOS version don't honor the winOverlay flag and erase. Better to erase the value @@ -775,11 +770,17 @@ palm_draw_drawTileBack( DrawCtx* p_dctx, const XP_Rect* rect, CellFlags flags ) static void palm_draw_drawTrayDivider( DrawCtx* p_dctx, const XP_Rect* rect, - XP_Bool selected ) + CellFlags flags ) { + PalmDrawCtx* dctx = (PalmDrawCtx*)p_dctx; XP_Rect lRect = *rect; + XP_Bool selected = (flags & CELL_HIGHLIGHT) != 0; + XP_Bool cursor = (flags & CELL_ISCURSOR) != 0; - draw_clearRect( p_dctx, &lRect ); + if ( cursor ) { + (void)WinSetBackColor( dctx->drawingPrefs->drawColors[COLOR_CURSOR] ); + } + WinEraseRectangle( (const RectangleType*)&lRect, 0 ); ++lRect.left; --lRect.width; @@ -798,7 +799,7 @@ palm_draw_drawTrayDivider( DrawCtx* p_dctx, const XP_Rect* rect, static void palm_bnw_draw_clearRect( DrawCtx* XP_UNUSED(p_dctx), const XP_Rect* rectP ) { - eraseRect( rectP ); + pmEraseRect( rectP ); } /* palm_draw_clearRect */ static void @@ -808,7 +809,7 @@ palm_clr_draw_clearRect( DrawCtx* p_dctx, const XP_Rect* rectP ) IndexedColorType oldColor; oldColor = WinSetBackColor( dctx->drawingPrefs->drawColors[COLOR_WHITE] ); - eraseRect( rectP ); + pmEraseRect( rectP ); WinSetBackColor( oldColor ); } /* palm_clr_draw_clearRect */ @@ -877,7 +878,7 @@ palm_draw_scoreBegin( DrawCtx* p_dctx, const XP_Rect* rect, WinGetClip( &dctx->oldScoreClip ); WinSetClip( (RectangleType*)rect ); - eraseRect( rect ); + pmEraseRect( rect ); } /* palm_draw_scoreBegin */ /* rectContainsRect: Dup of something in board.c. They could share if I were @@ -1176,7 +1177,7 @@ palm_draw_score_pendingScore( DrawCtx* p_dctx, const XP_Rect* rect, HIGHRES_PUSH_LOC(dctx); - if ( flags != 0 ) { + if ( flags != CELL_NONE ) { oclr = WinSetBackColor( dctx->drawingPrefs->drawColors[COLOR_CURSOR] ); } @@ -1184,7 +1185,7 @@ palm_draw_score_pendingScore( DrawCtx* p_dctx, const XP_Rect* rect, RctGetIntersection( &oldClip, (RectangleType*)rect, &newClip ); if ( newClip.extent.y > 0 ) { WinSetClip( &newClip ); - eraseRect( rect ); + pmEraseRect( rect ); if ( score >= 0 ) { XP_UCHAR tbuf[4]; @@ -1269,7 +1270,7 @@ palm_draw_drawTimer( DrawCtx* p_dctx, const XP_Rect* rInner, width = FntCharsWidth( (const char*)buf, len ); - eraseRect( &localR ); + pmEraseRect( &localR ); if ( width < localR.width ) { localR.left += localR.width - width; diff --git a/xwords4/wince/cedraw.c b/xwords4/wince/cedraw.c index a31d57b7d..faf8bafa3 100755 --- a/xwords4/wince/cedraw.c +++ b/xwords4/wince/cedraw.c @@ -591,15 +591,22 @@ DRAW_FUNC_NAME(drawTileBack)( DrawCtx* p_dctx, const XP_Rect* xprect, DLSTATIC void DRAW_FUNC_NAME(drawTrayDivider)( DrawCtx* p_dctx, const XP_Rect* rect, - XP_Bool selected ) + CellFlags flags ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; RECT rt; + XP_Bool selected = (flags & CELL_HIGHLIGHT) != 0; XPRtoRECT( &rt, rect ); ceClipToRect( hdc, &rt ); + + if ( (flags & CELL_ISCURSOR) != 0 ) { + FillRect( hdc, &rt, dctx->brushes[CE_FOCUS_COLOR] ); + InsetRect( &rt, 2, 0 ); + } + if ( selected ) { Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom ); } else {