mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-27 09:58:45 +01:00
include name of player whose turn it is in scoreboard entry, reducing
length until it fits. (Still needs polishing...)
This commit is contained in:
parent
e539b49948
commit
f80b1d74f2
3 changed files with 121 additions and 34 deletions
|
@ -155,7 +155,7 @@ curses_draw_drawRemText( DrawCtx* p_dctx, const XP_Rect* rInner,
|
||||||
} /* curses_draw_drawRemText */
|
} /* curses_draw_drawRemText */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fitIn( char* buf, int len, int* rem, char* str )
|
fitIn( char* buf, int len, int* rem, const char* str )
|
||||||
{
|
{
|
||||||
int slen = strlen(str);
|
int slen = strlen(str);
|
||||||
if ( !!rem && (*rem != 0) ) {
|
if ( !!rem && (*rem != 0) ) {
|
||||||
|
|
|
@ -170,8 +170,7 @@ layout_for_ht( GtkDrawCtx* dctx, XP_U16 ht )
|
||||||
|
|
||||||
if ( NULL == layout ) {
|
if ( NULL == layout ) {
|
||||||
FontPerSize* fps = g_malloc( sizeof(*fps) );
|
FontPerSize* fps = g_malloc( sizeof(*fps) );
|
||||||
dctx->fontsPerSize = g_list_insert( dctx->fontsPerSize,
|
dctx->fontsPerSize = g_list_insert( dctx->fontsPerSize, fps, 0 );
|
||||||
fps, 0 );
|
|
||||||
|
|
||||||
char font[32];
|
char font[32];
|
||||||
snprintf( font, sizeof(font), "helvetica normal %dpx", ht );
|
snprintf( font, sizeof(font), "helvetica normal %dpx", ht );
|
||||||
|
@ -709,10 +708,12 @@ gtk_draw_scoreBegin( DrawCtx* p_dctx, const XP_Rect* rect,
|
||||||
/* gdk_gc_set_clip_rectangle( dctx->drawGC, (GdkRectangle*)rect ); */
|
/* gdk_gc_set_clip_rectangle( dctx->drawGC, (GdkRectangle*)rect ); */
|
||||||
gtkEraseRect( dctx, rect );
|
gtkEraseRect( dctx, rect );
|
||||||
dctx->topFocus = dfs == DFS_TOP;
|
dctx->topFocus = dfs == DFS_TOP;
|
||||||
|
dctx->scoreIsVertical = rect->height > rect->width;
|
||||||
} /* gtk_draw_scoreBegin */
|
} /* gtk_draw_scoreBegin */
|
||||||
|
|
||||||
static PangoLayout*
|
static PangoLayout*
|
||||||
getLayoutToFitRect( GtkDrawCtx* dctx, const XP_UCHAR* str, const XP_Rect* rect )
|
getLayoutToFitRect( GtkDrawCtx* dctx, const XP_UCHAR* str, const XP_Rect* rect,
|
||||||
|
int* heightP )
|
||||||
{
|
{
|
||||||
PangoLayout* layout;
|
PangoLayout* layout;
|
||||||
float ratio, ratioH;
|
float ratio, ratioH;
|
||||||
|
@ -732,9 +733,15 @@ getLayoutToFitRect( GtkDrawCtx* dctx, const XP_UCHAR* str, const XP_Rect* rect )
|
||||||
ratio = ratioH;
|
ratio = ratioH;
|
||||||
}
|
}
|
||||||
height = 24.0 * ratio;
|
height = 24.0 * ratio;
|
||||||
|
if ( !!heightP && *heightP < height ) {
|
||||||
|
height = *heightP;
|
||||||
|
}
|
||||||
|
|
||||||
layout = layout_for_ht( dctx, height );
|
layout = layout_for_ht( dctx, height );
|
||||||
pango_layout_set_text( layout, (char*)str, len );
|
pango_layout_set_text( layout, (char*)str, len );
|
||||||
|
if ( !!heightP ) {
|
||||||
|
*heightP = height;
|
||||||
|
}
|
||||||
return layout;
|
return layout;
|
||||||
} /* getLayoutToFitRect */
|
} /* getLayoutToFitRect */
|
||||||
|
|
||||||
|
@ -747,7 +754,7 @@ gtkDrawDrawRemText( DrawCtx* p_dctx, const XP_Rect* rect, XP_S16 nTilesLeft,
|
||||||
PangoLayout* layout;
|
PangoLayout* layout;
|
||||||
|
|
||||||
XP_SNPRINTF( buf, sizeof(buf), "rem:%d", nTilesLeft );
|
XP_SNPRINTF( buf, sizeof(buf), "rem:%d", nTilesLeft );
|
||||||
layout = getLayoutToFitRect( dctx, buf, rect );
|
layout = getLayoutToFitRect( dctx, buf, rect, NULL );
|
||||||
|
|
||||||
if ( !!widthP ) {
|
if ( !!widthP ) {
|
||||||
int width, height;
|
int width, height;
|
||||||
|
@ -792,25 +799,74 @@ gtk_draw_drawRemText( DrawCtx* p_dctx, const XP_Rect* rInner,
|
||||||
} /* gtk_draw_drawRemText */
|
} /* gtk_draw_drawRemText */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
formatScoreText( XP_UCHAR* buf, XP_U16 bufLen, const DrawScoreInfo* dsi )
|
formatScoreText( PangoLayout* layout, XP_UCHAR* buf, XP_U16 bufLen,
|
||||||
|
const DrawScoreInfo* dsi, const XP_Rect* bounds,
|
||||||
|
XP_Bool scoreIsVertical, XP_U16* widthP, int* nLines )
|
||||||
{
|
{
|
||||||
XP_S16 score = dsi->totalScore;
|
XP_S16 score = dsi->totalScore;
|
||||||
XP_U16 nTilesLeft = dsi->nTilesLeft;
|
XP_U16 nTilesLeft = dsi->nTilesLeft;
|
||||||
XP_Bool isTurn = dsi->isTurn;
|
XP_Bool isTurn = dsi->isTurn;
|
||||||
int used;
|
XP_S16 maxWidth = bounds->width;
|
||||||
char* borders = "";
|
XP_UCHAR numBuf[16];
|
||||||
|
int width, height;
|
||||||
|
*nLines = 1;
|
||||||
|
|
||||||
if ( isTurn ) {
|
XP_SNPRINTF( numBuf, VSIZE(numBuf), "%d", score );
|
||||||
borders = "*";
|
|
||||||
}
|
|
||||||
|
|
||||||
used = XP_SNPRINTF( buf, bufLen, "%s%.3d", borders, score );
|
|
||||||
if ( (nTilesLeft < MAX_TRAY_TILES) && (nTilesLeft > 0) ) {
|
if ( (nTilesLeft < MAX_TRAY_TILES) && (nTilesLeft > 0) ) {
|
||||||
XP_UCHAR nbuf[10];
|
XP_UCHAR tmp[10];
|
||||||
XP_SNPRINTF( nbuf, VSIZE(nbuf), ":%d", nTilesLeft );
|
XP_SNPRINTF( tmp, VSIZE(tmp), ":%d", nTilesLeft );
|
||||||
(void)XP_STRCAT( buf, nbuf );
|
(void)XP_STRCAT( numBuf, tmp );
|
||||||
}
|
}
|
||||||
XP_SNPRINTF( buf+used, bufLen-used, "%s", borders );
|
|
||||||
|
if ( !!layout ) {
|
||||||
|
pango_layout_set_text( layout, (char*)numBuf, XP_STRLEN(numBuf) );
|
||||||
|
pango_layout_get_pixel_size( layout, &width, &height );
|
||||||
|
if ( !scoreIsVertical ) {
|
||||||
|
maxWidth -= width;
|
||||||
|
*widthP = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reformat name + ':' until it fits */
|
||||||
|
XP_UCHAR name[MAX_SCORE_LEN] = { 0 };
|
||||||
|
if ( isTurn && maxWidth > 0 ) {
|
||||||
|
XP_U16 len = 1 + XP_STRLEN( dsi->name ); /* +1 for "\0" */
|
||||||
|
if ( scoreIsVertical ) {
|
||||||
|
++*nLines;
|
||||||
|
} else {
|
||||||
|
++len; /* for ':' */
|
||||||
|
}
|
||||||
|
if ( len >= VSIZE(name) ) {
|
||||||
|
len = VSIZE(name) - 1;
|
||||||
|
}
|
||||||
|
for ( ; ; ) {
|
||||||
|
XP_SNPRINTF( name, len-1, "%s", dsi->name );
|
||||||
|
if ( !scoreIsVertical ) {
|
||||||
|
name[len-2] = ':';
|
||||||
|
name[len-1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
pango_layout_set_text( layout, (char*)name, len );
|
||||||
|
pango_layout_get_pixel_size( layout, &width, &height );
|
||||||
|
if ( width <= maxWidth ) {
|
||||||
|
if ( !scoreIsVertical ) {
|
||||||
|
*widthP += width;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( --len < 2 ) {
|
||||||
|
name[0] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( scoreIsVertical ) {
|
||||||
|
*widthP = bounds->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
XP_SNPRINTF( buf, bufLen, "%s%s%s", name, (*nLines>1? XP_CR:""), numBuf );
|
||||||
} /* formatScoreText */
|
} /* formatScoreText */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -819,16 +875,20 @@ gtk_draw_measureScoreText( DrawCtx* p_dctx, const XP_Rect* bounds,
|
||||||
XP_U16* widthP, XP_U16* heightP )
|
XP_U16* widthP, XP_U16* heightP )
|
||||||
{
|
{
|
||||||
GtkDrawCtx* dctx = (GtkDrawCtx*)p_dctx;
|
GtkDrawCtx* dctx = (GtkDrawCtx*)p_dctx;
|
||||||
XP_UCHAR buf[20];
|
XP_UCHAR buf[36];
|
||||||
PangoLayout* layout;
|
PangoLayout* layout;
|
||||||
int height, width;
|
int lineHeight = GTK_HOR_SCORE_HEIGHT, nLines;
|
||||||
|
|
||||||
formatScoreText( buf, VSIZE(buf), dsi );
|
layout = getLayoutToFitRect( dctx, "M", bounds, &lineHeight );
|
||||||
layout = getLayoutToFitRect( dctx, buf, bounds );
|
formatScoreText( layout, buf, VSIZE(buf), dsi, bounds,
|
||||||
pango_layout_get_pixel_size( layout, &width, &height );
|
dctx->scoreIsVertical, widthP, &nLines );
|
||||||
|
*heightP = nLines * lineHeight;
|
||||||
|
|
||||||
*widthP = width;
|
XP_U16 playerNum = dsi->playerNum;
|
||||||
*heightP = height;
|
XP_ASSERT( playerNum < VSIZE(dctx->scoreCache) );
|
||||||
|
XP_SNPRINTF( dctx->scoreCache[playerNum].str,
|
||||||
|
VSIZE(dctx->scoreCache[playerNum].str), "%s", buf );
|
||||||
|
dctx->scoreCache[playerNum].fontHt = lineHeight;
|
||||||
} /* gtk_draw_measureScoreText */
|
} /* gtk_draw_measureScoreText */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -836,35 +896,54 @@ gtk_draw_score_drawPlayer( DrawCtx* p_dctx, const XP_Rect* rInner,
|
||||||
const XP_Rect* rOuter, const DrawScoreInfo* dsi )
|
const XP_Rect* rOuter, const DrawScoreInfo* dsi )
|
||||||
{
|
{
|
||||||
GtkDrawCtx* dctx = (GtkDrawCtx*)p_dctx;
|
GtkDrawCtx* dctx = (GtkDrawCtx*)p_dctx;
|
||||||
XP_UCHAR scoreBuf[20];
|
|
||||||
XP_Bool hasCursor = (dsi->flags & CELL_ISCURSOR) != 0;
|
XP_Bool hasCursor = (dsi->flags & CELL_ISCURSOR) != 0;
|
||||||
GdkColor* cursor = NULL;
|
GdkColor* cursor = NULL;
|
||||||
|
XP_U16 playerNum = dsi->playerNum;
|
||||||
formatScoreText( scoreBuf, VSIZE(scoreBuf), dsi );
|
const XP_UCHAR* scoreBuf = dctx->scoreCache[playerNum].str;
|
||||||
|
XP_U16 fontHt = dctx->scoreCache[playerNum].fontHt;
|
||||||
|
|
||||||
if ( hasCursor ) {
|
if ( hasCursor ) {
|
||||||
cursor = &dctx->cursor;
|
cursor = &dctx->cursor;
|
||||||
gtkFillRect( dctx, rOuter, cursor );
|
gtkFillRect( dctx, rOuter, cursor );
|
||||||
}
|
}
|
||||||
|
|
||||||
gdk_gc_set_foreground( dctx->drawGC, &dctx->playerColors[dsi->playerNum] );
|
gdk_gc_set_foreground( dctx->drawGC, &dctx->playerColors[playerNum] );
|
||||||
|
|
||||||
if ( dsi->selected ) {
|
if ( dsi->selected ) {
|
||||||
XP_Rect selRect = *rOuter;
|
XP_Rect selRect = *rOuter;
|
||||||
XP_S16 diff = selRect.width - rInner->width;
|
XP_S16 diff;
|
||||||
if ( diff > 0 ) {
|
if ( dctx->scoreIsVertical ) {
|
||||||
selRect.width -= diff>>1;
|
diff = selRect.height - rInner->height;
|
||||||
selRect.left += diff>>2;
|
} else {
|
||||||
|
diff = selRect.width - rInner->width;
|
||||||
}
|
}
|
||||||
|
if ( diff > 0 ) {
|
||||||
|
if ( dctx->scoreIsVertical ) {
|
||||||
|
selRect.height -= diff>>1;
|
||||||
|
selRect.top += diff>>2;
|
||||||
|
} else {
|
||||||
|
selRect.width -= diff>>1;
|
||||||
|
selRect.left += diff>>2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gdk_draw_rectangle( DRAW_WHAT(dctx), dctx->drawGC,
|
gdk_draw_rectangle( DRAW_WHAT(dctx), dctx->drawGC,
|
||||||
TRUE, selRect.left, selRect.top,
|
TRUE, selRect.left, selRect.top,
|
||||||
selRect.width, selRect.height );
|
selRect.width, selRect.height );
|
||||||
|
if ( hasCursor ) {
|
||||||
|
gtkFillRect( dctx, rInner, cursor );
|
||||||
|
}
|
||||||
gtkEraseRect( dctx, rInner );
|
gtkEraseRect( dctx, rInner );
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_string_at( dctx, NULL, scoreBuf, rInner->height - 1,
|
/* XP_U16 fontHt = rInner->height; */
|
||||||
|
/* if ( strstr( scoreBuf, "\n" ) ) { */
|
||||||
|
/* fontHt >>= 1; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
draw_string_at( dctx, NULL, scoreBuf, fontHt/*-1*/,
|
||||||
rInner, XP_GTK_JUST_CENTER,
|
rInner, XP_GTK_JUST_CENTER,
|
||||||
&dctx->playerColors[dsi->playerNum], cursor );
|
&dctx->playerColors[playerNum], cursor );
|
||||||
|
|
||||||
} /* gtk_draw_score_drawPlayer */
|
} /* gtk_draw_score_drawPlayer */
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ enum {
|
||||||
,LAYOUT_NLAYOUTS
|
,LAYOUT_NLAYOUTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_SCORE_LEN 31
|
||||||
|
|
||||||
typedef struct GtkDrawCtx {
|
typedef struct GtkDrawCtx {
|
||||||
DrawCtxVTable* vtable;
|
DrawCtxVTable* vtable;
|
||||||
|
|
||||||
|
@ -58,9 +60,15 @@ typedef struct GtkDrawCtx {
|
||||||
/* new for gtk 2.0 */
|
/* new for gtk 2.0 */
|
||||||
PangoContext* pangoContext;
|
PangoContext* pangoContext;
|
||||||
GList* fontsPerSize;
|
GList* fontsPerSize;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
XP_UCHAR str[MAX_SCORE_LEN+1];
|
||||||
|
XP_U16 fontHt;
|
||||||
|
} scoreCache[MAX_NUM_PLAYERS];
|
||||||
|
|
||||||
XP_U16 trayOwner;
|
XP_U16 trayOwner;
|
||||||
XP_Bool topFocus;
|
XP_Bool topFocus;
|
||||||
|
XP_Bool scoreIsVertical;
|
||||||
} GtkDrawCtx;
|
} GtkDrawCtx;
|
||||||
|
|
||||||
typedef struct ClientStreamRec {
|
typedef struct ClientStreamRec {
|
||||||
|
|
Loading…
Reference in a new issue