Two large changes. First, layout board etc. based only on screen

dimensions and one constant giving the minimum height of a cell.
Replaces a bunch of constants that didn't scale to different sized
screens well.  Second, add the vertical scrollbar into the focus
rotation.  Once I have it showing that it's focussed it'll be easier
to figure out how to scroll the screen.
This commit is contained in:
ehouse 2008-09-28 17:50:04 +00:00
parent ae6610a94f
commit f8bb0ae202
6 changed files with 328 additions and 216 deletions

View file

@ -87,6 +87,7 @@ CFLAGS += -DCANT_DO_CMDBAR -DDRAW_LINK_DIRECT -DXWFEATURE_TURNCHANGENOTIFY
endif endif
endif endif
# CFLAGS += -DFORCE_SCROLL=3
CFLAGS += -DARM -I./ -I../common -I../relay CFLAGS += -DARM -I./ -I../common -I../relay
CFLAGS += -Wall -Wunused-parameter CFLAGS += -Wall -Wunused-parameter

View file

@ -21,44 +21,17 @@
#define _CEDEFINES_H_ #define _CEDEFINES_H_
#define CE_MAX_ROWS 15 #define CE_MAX_ROWS 15
#define CE_BOARD_LEFT_LH 8
#define CE_BOARD_LEFT_RH 0
#define CE_BOARD_WIDTH (CE_MAX_ROWS*CE_BOARD_SCALEH)
#define CE_TRAY_LEFT_RH 0
#define CE_TRAY_LEFT_LH 0
#define CE_DIVIDER_WIDTH 3
#define CE_TIMER_WIDTH 35
#define CE_SCORE_WIDTH (4 * 51)
#define CE_TIMER_HT_HORIZ CE_SCORE_HEIGHT #define TRAY_BORDER 7
#define CE_TIMER_HT_VERT CE_SCORE_WIDTH #define CELL_BORDER 3
#define CE_SCORE_TOP 0 #define MIN_CELL_WIDTH 12
#define CE_SCORE_HEIGHT 12 #define MIN_CELL_HEIGHT 13
#define CE_BOARD_TOP (CE_SCORE_TOP + CE_SCORE_HEIGHT) /* 1 below for what's subtracted from bparms->trayHeight */
#define CE_SCORE_LEFT CE_BOARD_LEFT_RH #define MIN_TILE_HEIGHT (((MIN_CELL_HEIGHT) + (TRAY_BORDER - CELL_BORDER)) + 1)
#define CE_TRAY_TOP (CE_BOARD_TOP + (CE_MAX_ROWS*CE_BOARD_SCALEV))
#define CE_TRAY_TOP_MAX CE_TRAY_TOP
#if defined TARGET_OS_WINCE /* Favor the tray over the scoreboard. */
# define CE_TRAY_SCALEH 34 #define SCORE_TWEAK 2
# define CE_TRAY_SCALEV 27
#elif defined TARGET_OS_WIN32
# define CE_TRAY_SCALEH 68
# define CE_TRAY_SCALEV 54
#endif
#define BUTTON_WIDTH 20
#define BUTTON_HEIGHT BUTTON_WIDTH
#define CE_TIMER_LEFT (CE_SCORE_WIDTH + CE_SCORE_LEFT)
#define CE_TIMER_TOP CE_SCORE_TOP
#define CE_TIMER_HEIGHT CE_SCORE_HEIGHT
#define MIN_CELL_WIDTH 10
#define MIN_CELL_HEIGHT 10
#define MIN_TRAY_HEIGHT 28
#define CE_MIN_SCORE_WIDTH 24 /* for vertical score case */
#endif #endif

View file

@ -294,7 +294,7 @@ ERROR
} /* ceClipToRect */ } /* ceClipToRect */
static void static void
makeTestBuf( CEDrawCtx* dctx, XP_UCHAR* buf, XP_UCHAR bufLen, RFIndex index ) makeTestBuf( CEDrawCtx* dctx, XP_UCHAR* buf, XP_U16 bufLen, RFIndex index )
{ {
switch( index ) { switch( index ) {
case RFONTS_TRAY: case RFONTS_TRAY:
@ -442,7 +442,8 @@ ceClearFontCache( CEDrawCtx* dctx )
} }
static void static void
ceFillFontInfo( LOGFONT* fontInfo, XP_U16 height/* , XP_Bool bold */ ) ceFillFontInfo( const CEDrawCtx* dctx, LOGFONT* fontInfo,
XP_U16 height/* , XP_Bool bold */ )
{ {
XP_MEMSET( fontInfo, 0, sizeof(*fontInfo) ); XP_MEMSET( fontInfo, 0, sizeof(*fontInfo) );
fontInfo->lfHeight = height; fontInfo->lfHeight = height;
@ -453,7 +454,8 @@ ceFillFontInfo( LOGFONT* fontInfo, XP_U16 height/* , XP_Bool bold */ )
/* fontInfo->lfWeight = FW_LIGHT; */ /* fontInfo->lfWeight = FW_LIGHT; */
/* } */ /* } */
wcscpy( fontInfo->lfFaceName, L"Arial" ); wcscpy( fontInfo->lfFaceName, IS_SMARTPHONE(dctx->globals)?
L"Segoe Condensed" : L"Tahoma" );
} }
static void static void
@ -482,7 +484,7 @@ ceBestFitFont( CEDrawCtx* dctx, XP_U16 soughtHeight, RFIndex index,
LOGFONT fontInfo; LOGFONT fontInfo;
HFONT testFont; HFONT testFont;
ceFillFontInfo( &fontInfo, testSize/* , index == RFONTS_SCORE_BOLD */ ); ceFillFontInfo( dctx, &fontInfo, testSize );
testFont = CreateFontIndirect( &fontInfo ); testFont = CreateFontIndirect( &fontInfo );
if ( !!testFont ) { if ( !!testFont ) {
@ -541,11 +543,10 @@ ceGetSizedFont( CEDrawCtx* dctx, XP_U16 height, RFIndex index )
} /* ceGetSizedFont */ } /* ceGetSizedFont */
static void static void
ceMeasureText( CEDrawCtx* dctx, const FontCacheEntry* fce, ceMeasureText( CEDrawCtx* dctx, HDC hdc, const FontCacheEntry* fce,
const XP_UCHAR* str, XP_S16 padding, const XP_UCHAR* str, XP_S16 padding,
XP_U16* widthP, XP_U16* heightP ) XP_U16* widthP, XP_U16* heightP )
{ {
HDC hdc = GetDC(dctx->mainWin);//globals->hdc;
XP_U16 height = 0; XP_U16 height = 0;
XP_U16 maxWidth = 0; XP_U16 maxWidth = 0;
@ -615,9 +616,19 @@ drawTextLines( CEDrawCtx* dctx, HDC hdc, const XP_UCHAR* text, XP_S16 padding,
static void static void
ceGetCharValHts( const XP_Rect* xprect, XP_U16* charHt, XP_U16* valHt ) ceGetCharValHts( const XP_Rect* xprect, XP_U16* charHt, XP_U16* valHt )
{ {
XP_U16 visHt = xprect->height - 5; XP_U16 visHt = xprect->height - TRAY_BORDER;
*valHt = visHt / 3; /* if tiles are wider than tall we can let them overlap vertically */
*charHt = visHt - *valHt; if ( xprect->width > xprect->height ) {
*valHt = visHt / 2;
if ( xprect->width > (xprect->height*2) ) {
*charHt = visHt;
} else {
*charHt = (visHt * 4) / 5;
}
} else {
*valHt = visHt / 3;
*charHt = visHt - *valHt;
}
} }
DLSTATIC XP_Bool DLSTATIC XP_Bool
@ -728,7 +739,7 @@ DRAW_FUNC_NAME(drawCell)( DrawCtx* p_dctx, const XP_Rect* xprect,
InsetRect( &rt, 1, 1 ); InsetRect( &rt, 1, 1 );
ceClipToRect( hdc, &rt ); ceClipToRect( hdc, &rt );
fce = ceGetSizedFont( dctx, XP_MIN(xprect->height,xprect->width) - 3, fce = ceGetSizedFont( dctx, XP_MIN(xprect->height-CELL_BORDER,xprect->width),
RFONTS_CELL ); RFONTS_CELL );
oldFont = SelectObject( hdc, fce->setFont ); oldFont = SelectObject( hdc, fce->setFont );
@ -1069,7 +1080,7 @@ DRAW_FUNC_NAME(drawBoardArrow)( DrawCtx* p_dctx, const XP_Rect* xprect,
} /* ce_draw_drawBoardArrow */ } /* ce_draw_drawBoardArrow */
DLSTATIC void DLSTATIC void
DRAW_FUNC_NAME(scoreBegin)( DrawCtx* p_dctx, const XP_Rect* rect, DRAW_FUNC_NAME(scoreBegin)( DrawCtx* p_dctx, const XP_Rect* xprect,
XP_U16 XP_UNUSED(numPlayers), XP_U16 XP_UNUSED(numPlayers),
DrawFocusState XP_UNUSED(dfs) ) DrawFocusState XP_UNUSED(dfs) )
{ {
@ -1078,11 +1089,11 @@ DRAW_FUNC_NAME(scoreBegin)( DrawCtx* p_dctx, const XP_Rect* rect,
XP_ASSERT( !!globals->hdc ); XP_ASSERT( !!globals->hdc );
SetBkColor( globals->hdc, dctx->globals->appPrefs.colors[CE_BKG_COLOR] ); SetBkColor( globals->hdc, dctx->globals->appPrefs.colors[CE_BKG_COLOR] );
dctx->scoreIsVertical = rect->height > rect->width; dctx->scoreIsVertical = xprect->height > xprect->width;
/* I don't think the clip rect's set at this point but drawing seems fine /* I don't think the clip rect's set at this point but drawing seems fine
anyway.... ceClearToBkground() is definitely needed here. */ anyway.... ceClearToBkground() is definitely needed here. */
ceClearToBkground( (CEDrawCtx*)p_dctx, rect ); ceClearToBkground( (CEDrawCtx*)p_dctx, xprect );
} /* ce_draw_scoreBegin */ } /* ce_draw_scoreBegin */
static void static void
@ -1106,7 +1117,8 @@ DRAW_FUNC_NAME(measureRemText)( DrawCtx* p_dctx, const XP_Rect* xprect,
{ {
if ( nTilesLeft > 0 ) { if ( nTilesLeft > 0 ) {
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
HDC hdc = dctx->globals->hdc; CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
XP_UCHAR buf[16]; XP_UCHAR buf[16];
const FontCacheEntry* fce; const FontCacheEntry* fce;
XP_U16 height; XP_U16 height;
@ -1117,12 +1129,12 @@ DRAW_FUNC_NAME(measureRemText)( DrawCtx* p_dctx, const XP_Rect* xprect,
formatRemText( nTilesLeft, dctx->scoreIsVertical, buf ); formatRemText( nTilesLeft, dctx->scoreIsVertical, buf );
height = xprect->height-2; height = xprect->height-2;
if ( height > CE_SCORE_HEIGHT ) { if ( height > globals->cellHt ) {
height = CE_SCORE_HEIGHT; height = globals->cellHt;
} }
fce = ceGetSizedFont( dctx, height, RFONTS_REM ); fce = ceGetSizedFont( dctx, height, RFONTS_REM );
oldFont = SelectObject( hdc, fce->setFont ); oldFont = SelectObject( hdc, fce->setFont );
ceMeasureText( dctx, fce, buf, 0/*CE_REM_PADDING*/, widthP, heightP ); ceMeasureText( dctx, hdc, fce, buf, 0, widthP, heightP );
(void)SelectObject( hdc, oldFont ); (void)SelectObject( hdc, oldFont );
} else { } else {
@ -1197,22 +1209,28 @@ DRAW_FUNC_NAME(measureScoreText)( DrawCtx* p_dctx, const XP_Rect* xprect,
XP_UCHAR buf[32]; XP_UCHAR buf[32];
HFONT oldFont; HFONT oldFont;
const FontCacheEntry* fce; const FontCacheEntry* fce;
XP_U16 height; XP_U16 fontHt, cellHt;
height = xprect->height-2; cellHt = globals->cellHt;
if ( height > CE_SCORE_HEIGHT ) { if ( !dctx->scoreIsVertical ) {
height = CE_SCORE_HEIGHT; cellHt -= SCORE_TWEAK;
} }
fontHt = xprect->height;
if ( fontHt > cellHt ) {
fontHt = cellHt;
}
fontHt -= 2; /* for whitespace top and bottom */
if ( !dsi->selected ) { if ( !dsi->selected ) {
height -= 2; fontHt -= 2; /* use smaller font for non-selected */
} }
fce = ceGetSizedFont( dctx, height,
dsi->selected ? RFONTS_SCORE_BOLD:RFONTS_SCORE );
oldFont = SelectObject( hdc, fce->setFont );
ceFormatScoreText( dctx, dsi, buf, sizeof(buf) ); ceFormatScoreText( dctx, dsi, buf, sizeof(buf) );
ceMeasureText( dctx, fce, buf, 0, widthP, heightP );
fce = ceGetSizedFont( dctx, fontHt,
dsi->selected ? RFONTS_SCORE_BOLD:RFONTS_SCORE );
oldFont = SelectObject( hdc, fce->setFont );
ceMeasureText( dctx, hdc, fce, buf, 0, widthP, heightP );
SelectObject( hdc, oldFont ); SelectObject( hdc, oldFont );
@ -1344,6 +1362,10 @@ DRAW_FUNC_NAME(drawTimer)( DrawCtx* p_dctx, const XP_Rect* rInner,
RECT rt; RECT rt;
PAINTSTRUCT ps; PAINTSTRUCT ps;
XP_Bool isNegative; XP_Bool isNegative;
HFONT oldFont;
const FontCacheEntry* fce;
fce = ceGetSizedFont( dctx, 0, RFONTS_SCORE );
XPRtoRECT( &rt, rInner ); XPRtoRECT( &rt, rInner );
@ -1369,8 +1391,11 @@ DRAW_FUNC_NAME(drawTimer)( DrawCtx* p_dctx, const XP_Rect* rInner,
SetTextColor( hdc, dctx->globals->appPrefs.colors[getPlayerColor(player)] ); SetTextColor( hdc, dctx->globals->appPrefs.colors[getPlayerColor(player)] );
SetBkColor( hdc, dctx->globals->appPrefs.colors[CE_BKG_COLOR] ); SetBkColor( hdc, dctx->globals->appPrefs.colors[CE_BKG_COLOR] );
ceClearToBkground( dctx, rInner ); ceClearToBkground( dctx, rInner );
drawTextLines( dctx, hdc, buf, CE_TIMER_PADDING, &rt,
DT_SINGLELINE | DT_VCENTER | DT_CENTER); oldFont = SelectObject( hdc, fce->setFont );
++rt.top;
ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt );
SelectObject( hdc, oldFont );
if ( !globals->hdc ) { if ( !globals->hdc ) {
EndPaint( dctx->mainWin, &ps ); EndPaint( dctx->mainWin, &ps );
@ -1413,7 +1438,8 @@ DRAW_FUNC_NAME(measureMiniWText)( DrawCtx* p_dctx, const XP_UCHAR* str,
XP_U16* widthP, XP_U16* heightP ) XP_U16* widthP, XP_U16* heightP )
{ {
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
ceMeasureText( dctx, NULL, str, CE_MINIW_PADDING, widthP, heightP ); HDC hdc = GetDC(dctx->mainWin);
ceMeasureText( dctx, hdc, NULL, str, CE_MINIW_PADDING, widthP, heightP );
*heightP += CE_MINI_V_PADDING; *heightP += CE_MINI_V_PADDING;
*widthP += CE_MINI_H_PADDING; *widthP += CE_MINI_H_PADDING;
} /* ce_draw_measureMiniWText */ } /* ce_draw_measureMiniWText */
@ -1664,11 +1690,13 @@ ce_draw_fromStream( CEDrawCtx* dctx, XWStreamCtxt* stream )
fce.glyphHt = (XP_U16)stream_getU8( stream ); fce.glyphHt = (XP_U16)stream_getU8( stream );
/* We need to read from the file no matter how many entries, but only /* We need to read from the file no matter how many entries, but only
populate what we have room for */ populate what we have room for -- in case N_RESIZE_FONTS was
different when file written. */
#ifndef DROP_CACHE #ifndef DROP_CACHE
if ( ii < N_RESIZE_FONTS && ii != RFONTS_CELL ) { if ( ii < N_RESIZE_FONTS ) {
LOGFONT fontInfo; LOGFONT fontInfo;
ceFillFontInfo( &fontInfo, fce.lfHeight ); /* XP_LOGF( "using height %d for index %d", fce.lfHeight, ii ); */
ceFillFontInfo( dctx, &fontInfo, fce.lfHeight );
fce.setFont = CreateFontIndirect( &fontInfo ); fce.setFont = CreateFontIndirect( &fontInfo );
XP_ASSERT( !!fce.setFont ); XP_ASSERT( !!fce.setFont );
@ -1676,4 +1704,4 @@ ce_draw_fromStream( CEDrawCtx* dctx, XWStreamCtxt* stream )
} }
#endif #endif
} }
} } /* ce_draw_fromStream */

View file

@ -57,7 +57,8 @@
#define MAX_LOADSTRING 100 #define MAX_LOADSTRING 100
#define SCROLLBAR_WIDTH 12 #define PPC_SCROLLBAR_WIDTH 12
#define MIN_SCROLLBAR_WIDTH 6
#define SCROLLBARID 0x4321 /* needs to be unique! */ #define SCROLLBARID 0x4321 /* needs to be unique! */
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
@ -157,6 +158,7 @@ static int messageBoxStream( CEAppGlobals* globals, XWStreamCtxt* stream,
wchar_t* title, XP_U16 buttons ); wchar_t* title, XP_U16 buttons );
static XP_Bool ceQueryFromStream( CEAppGlobals* globals, XWStreamCtxt* stream); static XP_Bool ceQueryFromStream( CEAppGlobals* globals, XWStreamCtxt* stream);
static XP_Bool isDefaultName( const XP_UCHAR* name ); static XP_Bool isDefaultName( const XP_UCHAR* name );
static void ceSetTitleFromName( CEAppGlobals* globals );
#if defined DEBUG && ! defined _WIN32_WCE #if defined DEBUG && ! defined _WIN32_WCE
@ -199,7 +201,8 @@ doCmd( const char* cmd )
static void static void
parseCmdLine( const char* cmdline ) parseCmdLine( const char* cmdline )
{ {
for ( ; ; ) { XP_U16 ii;
for ( ii = 0; ; ++ii ) {
const char* cmd; const char* cmd;
char ch; char ch;
char buf[64]; char buf[64];
@ -213,7 +216,9 @@ parseCmdLine( const char* cmdline )
len = cmd - cmdline; len = cmd - cmdline;
memcpy( buf, cmdline, cmd - cmdline ); memcpy( buf, cmdline, cmd - cmdline );
buf[len] = '\0'; buf[len] = '\0';
doCmd( buf ); if ( ii > 0 ) { /* skip argv[0] */
doCmd( buf );
}
if ( ch == '\0' ) { if ( ch == '\0' ) {
break; break;
} }
@ -375,46 +380,97 @@ updateScrollInfo( CEAppGlobals* globals, XP_U16 nHidden )
(void)SetScrollInfo( globals->scrollHandle, SB_CTL, &sinfo, TRUE ); (void)SetScrollInfo( globals->scrollHandle, SB_CTL, &sinfo, TRUE );
} }
LRESULT CALLBACK
scrollWindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
CEAppGlobals* globals = (CEAppGlobals*)GetWindowLongPtr( hWnd, GWL_USERDATA );
LRESULT result = 1;
/* XP_LOGF( "%s: event=%s (%d)", __func__, messageToStr(message), message ); */
/* Trap key events. Left and right always shift the focus off. Up and
down shift focus off IFF they're going to be no-ops on the theory that
the user needs to get some visual feedback and on some devices the
scrollbar isn't even drawn differently when focussed. */
if ( WM_KEYDOWN == message ) {
XP_Bool setFocus = XP_FALSE;
if ( (VK_RIGHT == wParam) ||
(VK_LEFT == wParam) ||
(VK_TAB == wParam) ) {
setFocus = XP_TRUE;
} else if ( (VK_UP == wParam) || (VK_DOWN == wParam) ) {
SCROLLINFO sinfo;
sinfo.cbSize = sizeof(sinfo);
sinfo.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
GetScrollInfo( globals->scrollHandle, SB_CTL, &sinfo );
if ( (VK_UP == wParam) && (sinfo.nPos <= sinfo.nMin) ) {
setFocus = XP_TRUE;
} else if ( (VK_DOWN == wParam)
&& (sinfo.nPos > (sinfo.nMax - sinfo.nPage)) ) {
setFocus = XP_TRUE;
}
}
if ( setFocus ) {
SetFocus( globals->hWnd );
result = 0;
}
}
if ( 0 != result ) {
result = CallWindowProc( globals->oldScrollProc, hWnd, message,
wParam, lParam );
}
return result;
} /* scrollWindowProc */
static void static void
showScroller( CEAppGlobals* globals, XP_U16 nHidden, XP_U16 x, XP_U16 y, makeScrollbar( CEAppGlobals* globals, XP_U16 nHidden, XP_U16 xx, XP_U16 yy,
XP_U16 width, XP_U16 height ) XP_U16 width, XP_U16 height )
{ {
HWND hwndSB;
/* Need to destroy it, or resize it, because board size may be changing
in case where portrait display's been flipped. */
if ( !!globals->scrollHandle ) { if ( !!globals->scrollHandle ) {
DestroyWindow( globals->scrollHandle ); DestroyWindow( globals->scrollHandle );
globals->scrollHandle = NULL; globals->scrollHandle = NULL;
} }
if ( !globals->scrollHandle ) { hwndSB = CreateWindow( TEXT("SCROLLBAR"), // Class name
HWND hwndSB; NULL, // Window text
// Window style
SBS_VERT|WS_VISIBLE|WS_CHILD,
xx + SCROLL_SHRINK, yy + 2,
width - SCROLL_SHRINK, height - 4,
globals->hWnd,
(HMENU)SCROLLBARID,// The control identifier
globals->hInst, // The instance handle
NULL ); // s'pposed to be NULL
hwndSB = CreateWindow( TEXT("SCROLLBAR"), // Class name globals->scrollHandle = hwndSB;
NULL, // Window text
// Window style
SBS_VERT|WS_VISIBLE|WS_CHILD,
x + SCROLL_SHRINK, y,
width - SCROLL_SHRINK, height + 1,
globals->hWnd,
(HMENU)SCROLLBARID,// The control identifier
globals->hInst, // The instance handle
NULL ); // s'pposed to be NULL
globals->scrollHandle = hwndSB; globals->oldScrollProc = (WNDPROC) GetWindowLongPtr( hwndSB,
updateScrollInfo( globals, nHidden ); GWL_WNDPROC );
XP_ASSERT( 0 == GetWindowLongPtr( hwndSB, GWL_USERDATA ) );
SetWindowLongPtr( hwndSB, GWL_WNDPROC, (LPARAM)scrollWindowProc );
SetWindowLongPtr( hwndSB, GWL_USERDATA, (LPARAM)globals );
EnableWindow( hwndSB, nHidden > 0 ); updateScrollInfo( globals, nHidden );
} EnableWindow( hwndSB, nHidden > 0 );
ShowWindow( globals->scrollHandle, SW_SHOW ); ShowWindow( globals->scrollHandle, SW_SHOW );
} /* showScroller */ } /* makeScrollbar */
static void static void
hideScroller( CEAppGlobals* globals ) removeScrollbar( CEAppGlobals* globals )
{ {
if ( !!globals->scrollHandle ) { if ( !!globals->scrollHandle ) {
ShowWindow( globals->scrollHandle, SW_HIDE ); DestroyWindow( globals->scrollHandle );
globals->scrollHandle = NULL;
} }
/* else there's nothing to do */ } /* removeScrollbar */
}
#endif #endif
typedef struct CEBoardParms { typedef struct CEBoardParms {
@ -433,49 +489,25 @@ typedef struct CEBoardParms {
XP_U16 boardLeft, trayLeft; XP_U16 boardLeft, trayLeft;
XP_U16 scoreWidth; XP_U16 scoreWidth;
XP_U16 scoreHeight; XP_U16 scoreHeight;
XP_Bool needsScroller; XP_U16 scrollWidth;
XP_Bool horiz; XP_Bool horiz;
#ifdef CEFEATURE_CANSCROLL
XP_Bool needsScroller;
#endif
} CEBoardParms; } CEBoardParms;
static XP_U16
sizeBoard( XP_U16* bdHeightP, /* INOUT */
XP_U16* nRowsP ) /* INOUT: on OUT, gives nRowsVisible */
{
/* given the initial max board height, figure how many rows are visible
and the adjusted heights of the board and tray. */
XP_U16 bdHeight = *bdHeightP;
XP_U16 nVisibleRows = *nRowsP;
XP_U16 vScale;
XP_U16 boardHtLimit;
vScale = bdHeight / nVisibleRows;
if ( vScale < MIN_CELL_HEIGHT ) {
vScale = MIN_CELL_HEIGHT;
}
/* Now adjust tray height to make board height a multiple */
boardHtLimit = nVisibleRows * vScale;
while ( boardHtLimit > bdHeight ) {
boardHtLimit -= vScale;
--nVisibleRows;
}
*bdHeightP = boardHtLimit;
*nRowsP = nVisibleRows;
return vScale;
} /* sizeBoard */
static void static void
figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms ) figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
{ {
RECT rc; RECT rc;
XP_U16 scrnWidth, scrnHeight; XP_U16 scrnWidth, scrnHeight;
XP_U16 trayVScale, boardLeft, trayLeft, scoreWidth, scoreHeight; XP_U16 trayVScale, scoreWidth, boardLeft, scoreHeight;
XP_U16 boardHt, boardWidth, hScale, vScale, nVisibleRows; XP_U16 hScale, vScale, nVisibleRows;
XP_U16 trayTop, boardTop; XP_U16 trayTop;
XP_Bool horiz; XP_Bool horiz;
XP_U16 trayWidth;
XP_U16 scrollWidth = 0; XP_U16 scrollWidth = 0;
XP_U16 numUnits;
XP_S16 num2Scroll;
GetClientRect( globals->hWnd, &rc ); GetClientRect( globals->hWnd, &rc );
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
@ -497,58 +529,98 @@ figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
scrnWidth = (XP_U16)(rc.right - rc.left); scrnWidth = (XP_U16)(rc.right - rc.left);
scrnHeight = (XP_U16)(rc.bottom - rc.top); scrnHeight = (XP_U16)(rc.bottom - rc.top);
XP_LOGF( "%s: scrnWidth: %d, scrnHeight: %d", __func__,
scrnWidth, scrnHeight );
horiz = (scrnHeight - CE_SCORE_HEIGHT) >= (scrnWidth - CE_MIN_SCORE_WIDTH); horiz = (scrnHeight/* - CE_SCORE_HEIGHT*/)
>= (scrnWidth/* - CE_MIN_SCORE_WIDTH*/);
nVisibleRows = nRows; nVisibleRows = nRows;
scoreHeight = horiz? CE_SCORE_HEIGHT : 0; /* Scoreboard is same height as cells (less SCORE_TWEAK) */
boardTop = scoreHeight; numUnits = (scrnHeight-MIN_TILE_HEIGHT) / MIN_CELL_HEIGHT;
num2Scroll = (nRows + 1) - numUnits; /* 1: scoreboard */
/* Try to make it fit without scrolling. But if necessary, reduce the if ( num2Scroll < 0 ) {
width for a scrollbar. */ num2Scroll = 0;
boardHt = scrnHeight - scoreHeight - MIN_TRAY_HEIGHT;
vScale = sizeBoard( &boardHt, &nVisibleRows );
if ( (nVisibleRows < nRows) && !IS_SMARTPHONE(globals) ) {
scrollWidth = SCROLLBAR_WIDTH;
} }
boardWidth = scrnWidth - scrollWidth; #ifdef FORCE_SCROLL
trayWidth = scrnWidth; if ( num2Scroll < FORCE_SCROLL ) {
num2Scroll = FORCE_SCROLL;
}
#endif
nVisibleRows -= num2Scroll;
/* apportion the extra pixels */
vScale = (scrnHeight-MIN_TILE_HEIGHT) / (nVisibleRows + (horiz? 1:0));
XP_LOGF( "%s: vScale: %d", __func__, vScale );
trayTop = (vScale * (nVisibleRows+(horiz? 1:0))); /* 1 for scoreboard */
if ( horiz ) { if ( horiz ) {
scoreWidth = scrnWidth; trayTop -= SCORE_TWEAK;
hScale = boardWidth / nRows; }
boardWidth = nRows * hScale; trayVScale = scrnHeight - trayTop;
/* center the board */
boardWidth += scrollWidth; /* If we have the space, make tiles 2* the size of cells */
boardLeft = (scrnWidth - boardWidth) / 2; /* center it all */ if ( nVisibleRows == nRows ) {
trayLeft = 0; XP_U16 nRowsIncSbrd = nRows + (horiz?1:0);
} else { while ( (vScale > MIN_CELL_HEIGHT) && (trayVScale < (2 * vScale)) ) {
/* move extra pixels into scoreboard */ trayVScale += nRowsIncSbrd;
hScale = (boardWidth - CE_MIN_SCORE_WIDTH) / nRows; trayTop -= nRowsIncSbrd;
boardWidth = hScale * nRows; --vScale;
scoreWidth = scrnWidth - boardWidth - scrollWidth; }
boardLeft = scoreWidth;
trayLeft = scoreWidth;
trayWidth -= scoreWidth;
} }
trayTop = boardHt + scoreHeight + 1; globals->cellHt = vScale;
trayVScale = scrnHeight - trayTop;
XP_LOGF( "vScale: %d; target: %d", vScale, MIN_CELL_HEIGHT );
if ( !horiz ) { XP_LOGF( "trayVScale: %d; target: %d", trayVScale, MIN_TILE_HEIGHT );
scoreHeight = scrnHeight;
#ifdef CEFEATURE_CANSCROLL
if ( nVisibleRows < nRows ) {
scrollWidth = PPC_SCROLLBAR_WIDTH;
} }
#endif
if ( horiz ) {
/* don't let scrollbar be wide out of proportion */
for ( ; ; ) {
hScale = (scrnWidth - scrollWidth) / nRows;
XP_LOGF( "1: scrollWidth: %d; hScale:%d", scrollWidth, hScale );
if ( scrollWidth > 0 ) {
boardLeft = 0;
scrollWidth = scrnWidth - (nRows * hScale);
} else {
boardLeft = (scrnWidth - scrollWidth - (hScale*nRows)) / 2;
}
XP_LOGF( "NOW: scrollWidth: %d; hScale:%d", scrollWidth, hScale );
if ( (hScale < scrollWidth)
&& (scrollWidth-nRows > MIN_SCROLLBAR_WIDTH) ) {
scrollWidth -= nRows;
} else {
break;
}
}
scoreWidth = scrnWidth;
} else {
hScale = (scrnWidth - scrollWidth) / (nRows + 2); /* double width? */
boardLeft = scrnWidth - scrollWidth - (hScale * nRows);
scoreWidth = boardLeft/* + scrollWidth*/;
}
scoreHeight = horiz? vScale - SCORE_TWEAK : scrnHeight;
if ( globals->gameInfo.timerEnabled ) { if ( globals->gameInfo.timerEnabled ) {
if ( horiz ) { if ( horiz ) {
scoreWidth -= CE_TIMER_WIDTH; bparms->timerWidth = scoreWidth / 6; /* arbitrarily, one sixth */
scoreWidth -= bparms->timerWidth;
bparms->timerLeft = scoreWidth; bparms->timerLeft = scoreWidth;
bparms->timerTop = 0; bparms->timerTop = 0;
bparms->timerWidth = CE_TIMER_WIDTH; bparms->timerHeight = scoreHeight;
bparms->timerHeight = CE_SCORE_HEIGHT;
} else { } else {
bparms->timerLeft = 0; bparms->timerLeft = 0;
bparms->timerHeight = CE_SCORE_HEIGHT * 2; bparms->timerHeight = vScale * 2;
bparms->timerTop = scrnHeight - bparms->timerHeight; bparms->timerTop = scrnHeight - bparms->timerHeight;
bparms->timerWidth = scoreWidth; bparms->timerWidth = scoreWidth;
@ -559,27 +631,28 @@ figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
bparms->scrnWidth = scrnWidth; bparms->scrnWidth = scrnWidth;
bparms->boardHScale = hScale; bparms->boardHScale = hScale;
bparms->boardVScale = vScale; bparms->boardVScale = vScale;
bparms->boardTop = boardTop; bparms->boardTop = horiz? scoreHeight : 0;
bparms->trayTop = trayTop; bparms->trayTop = trayTop;
bparms->trayHeight = trayVScale; bparms->trayHeight = trayVScale;
bparms->trayWidth = trayWidth; bparms->trayWidth = horiz? scrnWidth: scrnWidth - scoreWidth;
bparms->boardLeft = boardLeft; bparms->boardLeft = boardLeft;
bparms->trayLeft = trayLeft; bparms->trayLeft = horiz? 0 : scoreWidth;
bparms->scoreWidth = scoreWidth; bparms->scoreWidth = scoreWidth;
bparms->scoreHeight = scoreHeight; bparms->scoreHeight = scoreHeight;
bparms->scrollWidth = scrollWidth;
bparms->horiz = horiz; bparms->horiz = horiz;
#ifdef CEFEATURE_CANSCROLL #ifdef CEFEATURE_CANSCROLL
bparms->needsScroller = nVisibleRows < nRows; bparms->needsScroller = nVisibleRows < nRows;
if ( bparms->needsScroller && !IS_SMARTPHONE(globals) ) { if ( bparms->needsScroller ) {
XP_U16 boardRight = boardLeft + (nRows * hScale); XP_U16 boardRight;
showScroller( globals, nRows - nVisibleRows, boardRight = bparms->boardLeft + (nRows * hScale);
boardRight, boardTop, makeScrollbar( globals, nRows - nVisibleRows,
scrollWidth, boardHt ); boardRight, bparms->boardTop,
XP_LOGF( "NEEDING SCROLLBAR!!!!" ); scrollWidth,
XP_LOGF( "%d rows hidden", nRows - nVisibleRows ); vScale * nVisibleRows );
} else { } else {
hideScroller( globals ); removeScrollbar( globals );
} }
#endif #endif
} /* figureBoardParms */ } /* figureBoardParms */
@ -590,6 +663,7 @@ setOwnedRects( CEAppGlobals* globals, XP_U16 nRows,
{ {
if ( bparms->horiz ) { if ( bparms->horiz ) {
RECT tmp; RECT tmp;
XP_U16 scrollWidth = bparms->scrollWidth;
tmp.top = bparms->scoreHeight; /* Same for both */ tmp.top = bparms->scoreHeight; /* Same for both */
tmp.bottom = bparms->trayTop; /* Same for both */ tmp.bottom = bparms->trayTop; /* Same for both */
@ -599,7 +673,7 @@ setOwnedRects( CEAppGlobals* globals, XP_U16 nRows,
XP_MEMCPY( &globals->ownedRects[OWNED_RECT_LEFT], &tmp, XP_MEMCPY( &globals->ownedRects[OWNED_RECT_LEFT], &tmp,
sizeof(globals->ownedRects[OWNED_RECT_LEFT]) ); sizeof(globals->ownedRects[OWNED_RECT_LEFT]) );
tmp.left = tmp.right + (bparms->boardHScale * nRows); tmp.left = tmp.right + (bparms->boardHScale * nRows) + scrollWidth;
tmp.right = bparms->scrnWidth; tmp.right = bparms->scrnWidth;
XP_MEMCPY( &globals->ownedRects[OWNED_RECT_RIGHT], &tmp, XP_MEMCPY( &globals->ownedRects[OWNED_RECT_RIGHT], &tmp,
sizeof(globals->ownedRects[OWNED_RECT_RIGHT]) ); sizeof(globals->ownedRects[OWNED_RECT_RIGHT]) );
@ -608,6 +682,11 @@ setOwnedRects( CEAppGlobals* globals, XP_U16 nRows,
} }
} /* setOwnedRects */ } /* setOwnedRects */
/* PENDING cePositionBoard gets called a lot when the screen size hasn't
changed. It'd be better to cache the size used to do layout and not
repeat those steps (including possibly nuking and rebuilding a
scrollbar). */
static XP_Bool static XP_Bool
cePositionBoard( CEAppGlobals* globals ) cePositionBoard( CEAppGlobals* globals )
{ {
@ -633,8 +712,7 @@ cePositionBoard( CEAppGlobals* globals )
board_setScale( globals->game.board, bparms.boardHScale, board_setScale( globals->game.board, bparms.boardHScale,
bparms.boardVScale ); bparms.boardVScale );
board_setScoreboardLoc( globals->game.board, CE_SCORE_LEFT, board_setScoreboardLoc( globals->game.board, 0, 0, bparms.scoreWidth,
CE_SCORE_TOP, bparms.scoreWidth,
bparms.scoreHeight, bparms.horiz ); bparms.scoreHeight, bparms.horiz );
board_setShowColors( globals->game.board, globals->appPrefs.showColors ); board_setShowColors( globals->game.board, globals->appPrefs.showColors );
board_setYOffset( globals->game.board, 0 ); board_setYOffset( globals->game.board, 0 );
@ -642,10 +720,14 @@ cePositionBoard( CEAppGlobals* globals )
board_prefsChanged( globals->game.board, &globals->appPrefs.cp ); board_prefsChanged( globals->game.board, &globals->appPrefs.cp );
board_setTrayLoc( globals->game.board, bparms.trayLeft, bparms.trayTop, board_setTrayLoc( globals->game.board, bparms.trayLeft, bparms.trayTop,
bparms.trayWidth, bparms.trayHeight, CE_DIVIDER_WIDTH ); bparms.trayWidth, bparms.trayHeight,
bparms.trayWidth/40 ); /* 1/8 of a tile width, roughly */
server_prefsChanged( globals->game.server, &globals->appPrefs.cp ); server_prefsChanged( globals->game.server, &globals->appPrefs.cp );
#if ! defined _WIN32_WCE && defined DEBUG
ceSetTitleFromName( globals );
#endif
return erase; return erase;
} /* cePositionBoard */ } /* cePositionBoard */
@ -689,6 +771,11 @@ ceSetTitleFromName( CEAppGlobals* globals )
if ( colonPos != NULL ) { if ( colonPos != NULL ) {
*colonPos = 0; *colonPos = 0;
} }
#if ! defined _WIN32_WCE && defined DEBUG
swprintf( &widebuf[wcslen(widebuf)], L" %dx%d",
globals->dbWidth, globals->dbHeight );
#endif
} }
SendMessage( globals->hWnd, WM_SETTEXT, 0, (long)widebuf ); SendMessage( globals->hWnd, WM_SETTEXT, 0, (long)widebuf );
@ -868,7 +955,8 @@ ceLoadPrefs( CEAppGlobals* globals )
if ( fileH != INVALID_HANDLE_VALUE ) { if ( fileH != INVALID_HANDLE_VALUE ) {
XP_U32 fileSize = GetFileSize( fileH, NULL ); XP_U32 fileSize = GetFileSize( fileH, NULL );
XP_U16 curVersion; XP_U16 curVersion;
if ( fileSize >= sizeof(curVersion) && peekVersion( fileH, &curVersion ) ) { if ( fileSize >= sizeof(curVersion) && peekVersion( fileH,
&curVersion ) ) {
CEAppPrefs tmpPrefs; CEAppPrefs tmpPrefs;
if ( curVersion == CUR_CE_PREFS_FLAGS ) { if ( curVersion == CUR_CE_PREFS_FLAGS ) {
if ( fileSize >= sizeof( CEAppPrefs ) ) { if ( fileSize >= sizeof( CEAppPrefs ) ) {
@ -1781,8 +1869,8 @@ handleScroll( CEAppGlobals* globals, XP_S16 pos, /* only valid for THUMB* */
XP_Bool result = XP_FALSE; XP_Bool result = XP_FALSE;
if ( wnd == globals->scrollHandle ) { if ( wnd == globals->scrollHandle ) {
XP_S16 newOffset;
XP_U16 curYOffset = board_getYOffset( globals->game.board ); XP_U16 curYOffset = board_getYOffset( globals->game.board );
XP_S16 newOffset = curYOffset;
XP_ASSERT( !!globals->game.board ); XP_ASSERT( !!globals->game.board );
@ -1792,21 +1880,20 @@ handleScroll( CEAppGlobals* globals, XP_S16 pos, /* only valid for THUMB* */
case SB_LINEUP: // Scrolls one line up case SB_LINEUP: // Scrolls one line up
case SB_PAGEUP: // case SB_PAGEUP: //
newOffset = curYOffset - 1; --newOffset;
break; break;
case SB_LINEDOWN: // Scrolls one line down case SB_LINEDOWN: // Scrolls one line down
case SB_PAGEDOWN: // Scrolls one page down case SB_PAGEDOWN: // Scrolls one page down
newOffset = curYOffset + 1; ++newOffset;
break; break;
case SB_THUMBTRACK: /* still dragging; don't redraw */ case SB_THUMBTRACK: /* still dragging; don't redraw */
case SB_THUMBPOSITION: case SB_THUMBPOSITION:
newOffset = pos; newOffset = pos;
break;
default: default:
newOffset = -1; break;
/* do nothing */ /* do nothing: leave newOffset == curYOffset */
} }
result = curYOffset != newOffset result = curYOffset != newOffset
@ -1961,22 +2048,43 @@ ceCheckHandleFocusKey( CEAppGlobals* globals, WPARAM wParam, LPARAM lParam,
} }
if ( !*handledP && incr != 0 && !keyDown ) { if ( !*handledP && incr != 0 && !keyDown ) {
BoardObjectType order[] = { OBJ_SCORE, OBJ_BOARD, OBJ_TRAY }; BoardObjectType orderScroll[] = {
OBJ_SCORE, OBJ_BOARD, OBJ_NONE, OBJ_TRAY };
BoardObjectType orderNoScroll[] = {
OBJ_SCORE, OBJ_BOARD, OBJ_TRAY };
BoardObjectType* order;
XP_U16 orderLen;
BoardObjectType cur = board_getFocusOwner( board ); BoardObjectType cur = board_getFocusOwner( board );
XP_U16 index = 0; XP_U16 index = 0;
XP_LOGF( "here" );
if ( cur != OBJ_NONE ) { if ( !!globals->scrollHandle ) {
order = orderScroll;
orderLen = VSIZE(orderScroll);
} else {
order = orderNoScroll;
orderLen = VSIZE(orderNoScroll);
}
if ( !!globals->scrollHandle || (cur != OBJ_NONE) ) {
for ( ; ; ) { for ( ; ; ) {
if ( order[index] == cur ) { if ( order[index] == cur ) {
break; break;
} }
++index; ++index;
XP_ASSERT( index < 3 ); XP_ASSERT( index < orderLen );
} }
index = (index + 3 + incr) % 3; index = (index + orderLen + incr) % orderLen;
} }
XP_LOGF( "%s: calling board_focusChanged", __func__ ); XP_LOGF( "%s: calling board_focusChanged", __func__ );
draw = board_focusChanged( board, order[index], XP_TRUE ); draw = board_focusChanged( board, order[index], XP_TRUE );
if ( !!globals->scrollHandle ) {
if ( order[index] == OBJ_NONE ) {
SetFocus( globals->scrollHandle );
} else {
SetFocus( globals->hWnd );
}
}
} }
} }
return draw; return draw;
@ -2016,7 +2124,7 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if ( message == WM_CREATE ) { if ( message == WM_CREATE ) {
globals = ((CREATESTRUCT*)lParam)->lpCreateParams; globals = ((CREATESTRUCT*)lParam)->lpCreateParams;
SetWindowLong( hWnd, GWL_USERDATA, (long)globals ); SetWindowLongPtr( hWnd, GWL_USERDATA, (long)globals );
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
globals->hwndCB = makeCommandBar( hWnd, globals->hInst ); globals->hwndCB = makeCommandBar( hWnd, globals->hInst );
#endif #endif
@ -2026,7 +2134,7 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
#endif #endif
} else { } else {
/* XP_LOGF( "%s: event=%s (%d)", __func__, messageToStr(message), message ); */ /* XP_LOGF( "%s: event=%s (%d)", __func__, messageToStr(message), message ); */
globals = (CEAppGlobals*)GetWindowLong( hWnd, GWL_USERDATA ); globals = (CEAppGlobals*)GetWindowLongPtr( hWnd, GWL_USERDATA );
switch (message) { switch (message) {

View file

@ -127,9 +127,11 @@ typedef struct CEAppGlobals {
RECT ownedRects[N_OWNED_RECTS]; RECT ownedRects[N_OWNED_RECTS];
XP_U16 flags; /* bits defined below */ XP_U16 flags; /* bits defined below */
XP_U16 cellHt; /* how tall is a cell given current layout */
#ifdef CEFEATURE_CANSCROLL #ifdef CEFEATURE_CANSCROLL
HWND scrollHandle; HWND scrollHandle;
WNDPROC oldScrollProc;
#endif #endif
CeSocketWrapper* socketWrap; CeSocketWrapper* socketWrap;

View file

@ -198,32 +198,32 @@ ceCenterCtl( HWND hDlg, XP_U16 resID )
} }
} /* ceCenterCtl */ } /* ceCenterCtl */
XP_Bool /* XP_Bool */
ceIsLandscape( CEAppGlobals* globals ) /* ceIsLandscape( CEAppGlobals* globals ) */
{ /* { */
XP_U16 width, height; /* XP_U16 width, height; */
XP_Bool landscape; /* XP_Bool landscape; */
XP_ASSERT( !!globals ); /* XP_ASSERT( !!globals ); */
XP_ASSERT( !!globals->hWnd ); /* XP_ASSERT( !!globals->hWnd ); */
if ( 0 ) { /* if ( 0 ) { */
#if defined DEBUG && !defined _WIN32_WCE /* #if defined DEBUG && !defined _WIN32_WCE */
} else if ( globals->dbWidth != 0 ) { /* } else if ( globals->dbWidth != 0 ) { */
width = globals->dbWidth; /* width = globals->dbWidth; */
height = globals->dbHeight; /* height = globals->dbHeight; */
#endif /* #endif */
} else { /* } else { */
RECT rect; /* RECT rect; */
GetClientRect( globals->hWnd, &rect ); /* GetClientRect( globals->hWnd, &rect ); */
width = (XP_U16)(rect.right - rect.left); /* width = (XP_U16)(rect.right - rect.left); */
height = (XP_U16)(rect.bottom - rect.top); /* height = (XP_U16)(rect.bottom - rect.top); */
} /* } */
landscape = (height - CE_SCORE_HEIGHT) /* landscape = (height - CE_SCORE_HEIGHT) */
< (width - CE_MIN_SCORE_WIDTH); /* < (width - CE_MIN_SCORE_WIDTH); */
return landscape; /* return landscape; */
} /* ceIsLandscape */ /* } /\* ceIsLandscape *\/ */
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
static XP_Bool static XP_Bool