Generalize code for moving lower items up to cover hidden items, and

use for role-config and juggle buttons in gameinfo dlg.
This commit is contained in:
ehouse 2009-10-17 04:01:59 +00:00
parent 1929505c10
commit 0d326c0252
3 changed files with 202 additions and 48 deletions

View file

@ -51,6 +51,12 @@ typedef struct _GameInfoState {
XP_Bool isNewGame; /* newGame or GameInfo */
XP_Bool userCancelled; /* OUT param */
/* For tracking when to move stuff up/down */
XP_Bool juggleHidden;
XP_Bool roleConfigHidden;
XP_U16 juggleSpacing;
XP_U16 configSpacing;
GInfoResults results;
CePrefsPrefs* prefsPrefs;
@ -286,57 +292,39 @@ stateToGameInfo( GameInfoState* state )
} /* stateToGameInfo */
static void
raiseForHiddenPlayers( GameInfoState* state, XP_U16 nPlayers )
raiseForJuggle( GameInfoState* state, XP_Bool nowHidden )
{
HWND hDlg = state->dlgHdr.hDlg;
XP_U16 ii;
XP_S16 moveY;
if ( nPlayers != state->prevNPlayers ) {
if ( !state->moveIds ) {
XP_S16 ids[32];
HWND child;
RECT rect;
XP_U16 playersBottom;
ceGetItemRect( hDlg, NAME_EDIT4, &rect );
playersBottom = rect.bottom;
ceGetItemRect( hDlg, NAME_EDIT3, &rect );
state->playersSpacing = playersBottom - rect.bottom;
for ( child = GetWindow( hDlg, GW_CHILD ), ii = 0;
!!child;
child = GetWindow( child, GW_HWNDNEXT ) ) {
XP_S16 resID = GetDlgCtrlID( child );
if ( resID > 0 ) {
ceGetItemRect( hDlg, resID, &rect );
if ( rect.top > playersBottom ) {
XP_ASSERT( ii < VSIZE(ids)-1 );
ids[ii] = resID;
++ii;
}
}
}
state->moveIds = XP_MALLOC( state->dlgHdr.globals->mpool,
sizeof(state->moveIds[0]) * ii );
XP_MEMCPY( state->moveIds, ids, sizeof(state->moveIds[0]) * ii );
state->nMoveIds = ii;
}
moveY = state->playersSpacing * (nPlayers - state->prevNPlayers);
for ( ii = 0; ii < state->nMoveIds; ++ii ) {
ceMoveItem( hDlg, state->moveIds[ii], 0, moveY );
}
state->prevNPlayers = nPlayers;
#ifdef _WIN32_WCE
if ( IS_SMARTPHONE(state->dlgHdr.globals) ) {
SendMessage( hDlg, DM_RESETSCROLL, (WPARAM)FALSE, (LPARAM)TRUE );
}
#endif
if ( nowHidden != state->juggleHidden ) {
ceDlgMoveBelow( &state->dlgHdr, GIJUGGLE_BUTTON,
state->juggleSpacing * (nowHidden? -1 : 1) );
state->juggleHidden = nowHidden;
}
}
#ifndef XWFEATURE_STANDALONE_ONLY
static void
raiseForRoleChange( GameInfoState* state, DeviceRole role )
{
XP_Bool configHidden = role == SERVER_STANDALONE;
if ( configHidden != state->roleConfigHidden ) {
ceDlgMoveBelow( &state->dlgHdr, state->roleComboId,
state->configSpacing * (configHidden? -1 : 1) );
state->roleConfigHidden = configHidden;
}
}
#endif
static void
raiseForHiddenPlayers( GameInfoState* state, XP_U16 nPlayers )
{
if ( nPlayers != state->prevNPlayers ) {
ceDlgMoveBelow( &state->dlgHdr, NAME_EDIT4,
state->playersSpacing
* (nPlayers - state->prevNPlayers) );
state->prevNPlayers = nPlayers;
}
} /* raiseForHiddenPlayers */
static void
handlePrefsButton( HWND hDlg, CEAppGlobals* globals, GameInfoState* state )
{
@ -378,6 +366,7 @@ handleConnOptionsButton( GameInfoState* state )
GETCURSEL(globals), 0, 0L);
value.ng_role = role;
newg_attrChanged( state->newGameCtx, NG_ATTR_ROLE, value );
raiseForRoleChange( state, role );
} /* handleConnOptionsButton */
#endif
@ -462,6 +451,9 @@ ceEnableAttrProc( void* closure, NewGameAttr attr, XP_TriEnable enable )
GameInfoState* state = (GameInfoState*)closure;
XP_U16 resID = resIDForAttr( state, attr );
doForNWEnable( state->dlgHdr.hDlg, resID, enable );
if ( resID == GIJUGGLE_BUTTON ) {
raiseForJuggle( state, enable == TRI_ENAB_HIDDEN );
}
} /* ceEnableAttrProc */
static void
@ -547,6 +539,7 @@ ceSetAttrProc(void* closure, NewGameAttr attr, const NGValue value )
case NG_ATTR_ROLE:
SendDlgItemMessage( state->dlgHdr.hDlg, resID, SETCURSEL(globals),
value.ng_role, 0L );
raiseForRoleChange( state, value.ng_role );
break;
#endif
case NG_ATTR_NPLAYHEADER:
@ -644,7 +637,16 @@ GameInfo( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
state->prevNPlayers = MAX_NUM_PLAYERS;
ceDlgSetup( &state->dlgHdr, hDlg, DLG_STATE_TRAPBACK );
state->playersSpacing = ceDistanceBetween( hDlg, NAME_EDIT3, NAME_EDIT4 );
state->juggleSpacing = ceDistanceBetween( state->dlgHdr.hDlg,
GIJUGGLE_BUTTON,
IDC_DICTLABEL );
#ifndef XWFEATURE_STANDALONE_ONLY
state->configSpacing = ceDistanceBetween( state->dlgHdr.hDlg,
IDC_ROLELABEL,
GIROLECONF_BUTTON );
ceDlgComboShowHide( &state->dlgHdr, IDC_ROLECOMBO );
#endif
ceDlgComboShowHide( &state->dlgHdr, IDC_NPLAYERSCOMBO );
@ -796,9 +798,13 @@ WrapGameInfoDialog( CEAppGlobals* globals, XP_Bool isNewGame,
XP_UCHAR* dictName, XP_U16 dictNameLen,
GInfoResults* results )
{
GameInfoState state;
GameInfoState state;
XP_U16 resIDs[48];
XP_MEMSET( &state, 0, sizeof(state) );
state.dlgHdr.globals = globals;
state.dlgHdr.resIDs = resIDs;
state.dlgHdr.nResIDs = VSIZE(resIDs);
state.isNewGame = isNewGame;
state.prefsPrefs = prefsPrefs;
state.newDictName = dictName;

View file

@ -183,6 +183,17 @@ ceMoveItem( HWND hDlg, XP_U16 resID, XP_S16 byX, XP_S16 byY )
}
} /* ceMoveItem */
XP_U16
ceDistanceBetween( HWND hDlg, XP_U16 resID1, XP_U16 resID2 )
{
RECT rect;
ceGetItemRect( hDlg, resID1, &rect );
XP_U16 top = rect.top;
ceGetItemRect( hDlg, resID2, &rect );
XP_ASSERT( rect.top > top );
return rect.top - top;
}
#if 0
/* This has not been tested with ceMoveItem... */
void
@ -360,6 +371,91 @@ ceCenterBy( HWND hDlg, XP_U16 byHowMuch )
}
} /* ceCenterBy */
#define MAX_DLG_ROWS 20
typedef struct _DlgRow {
XP_U16 top, bottom;
XP_U16 nIds;
XP_U16 ids[12];
} DlgRow;
typedef struct _DlgRows {
DlgRow rows[MAX_DLG_ROWS];
XP_U16 nRows;
} DlgRows;
static void
insertId( HWND hDlg, DlgRows* rows, XP_U16 id )
{
RECT rect;
XP_U16 ii;
DlgRow* row;
ceGetItemRect( hDlg, id, &rect );
// Find an entry it fits in, or add a new one.
for ( ii = 0; ii < MAX_DLG_ROWS; ++ii ) {
row = &rows->rows[ii];
if ( row->bottom == 0 ) {
row->top = rect.top;
row->bottom = rect.bottom;
++rows->nRows;
break;
} else if ( rect.top >= row->bottom ) {
/* continue */
} else if ( rect.bottom <= row->top ) {
/* continue */
} else {
if ( row->top < rect.top ) {
row->top = rect.top;
}
if ( row->bottom > rect.bottom ) {
row->bottom = rect.bottom;
}
break;
}
}
XP_ASSERT( ii < VSIZE(rows->rows) );
row->ids[row->nIds++] = id;
XP_ASSERT( row->nIds < VSIZE(row->ids) );
}
static void
buildIdList( CeDlgHdr* dlgHdr )
{
HWND child;
XP_U16 ii, jj;
DlgRows rows;
XP_U16 nResIDsUsed;
XP_MEMSET( &rows, 0, sizeof(rows) );
for ( child = GetWindow( dlgHdr->hDlg, GW_CHILD ), ii = 0;
!!child;
child = GetWindow( child, GW_HWNDNEXT ) ) {
XP_S16 resID = GetDlgCtrlID( child );
if ( resID > 0 ) {
insertId( dlgHdr->hDlg, &rows, resID );
}
}
/* might need to sort first */
nResIDsUsed = 0;
for ( ii = 0; ii < rows.nRows; ++ii ) {
DlgRow* row = &rows.rows[ii];
for ( jj = 0; jj < row->nIds; ++jj ) {
XP_U16 id = row->ids[jj];
dlgHdr->resIDs[nResIDsUsed++] = id;
XP_ASSERT( nResIDsUsed < dlgHdr->nResIDs );
}
dlgHdr->resIDs[nResIDsUsed++] = 0;
XP_ASSERT( nResIDsUsed <= dlgHdr->nResIDs );
}
dlgHdr->nResIDsUsed = nResIDsUsed;
}
#define TITLE_HT 20 /* Need to get this from the OS */
void
ceDlgSetup( CeDlgHdr* dlgHdr, HWND hDlg, DlgStateTask doWhat )
@ -412,6 +508,11 @@ ceDlgSetup( CeDlgHdr* dlgHdr, HWND hDlg, DlgStateTask doWhat )
(void)SetScrollInfo( hDlg, SB_VERT, &sinfo, FALSE );
}
if ( !!dlgHdr->resIDs ) {
buildIdList( dlgHdr );
}
dlgHdr->doWhat = doWhat;
#ifdef _WIN32_WCE
@ -512,6 +613,45 @@ ceDoDlgHandle( CeDlgHdr* dlgHdr, UINT message, WPARAM wParam, LPARAM lParam )
return handled;
} /* ceDoDlgHandle */
void
ceDlgMoveBelow( CeDlgHdr* dlgHdr, XP_U16 resID, XP_S16 distance )
{
XP_U16 ii;
XP_ASSERT( !!dlgHdr->resIDs );
XP_U16 nResIDsUsed = dlgHdr->nResIDsUsed;
for ( ii = 0; ii < nResIDsUsed; ++ii ) {
if ( dlgHdr->resIDs[ii] == resID ) {
break;
}
}
if ( ii < nResIDsUsed ) { /* found it? */
while ( dlgHdr->resIDs[ii] != 0 ) { /* skip to end of row */
++ii;
XP_ASSERT( ii < nResIDsUsed ); /* found it? */
}
++ii; /* skip past the 0 */
for ( ; ii < nResIDsUsed; ++ii ) {
XP_U16 id = dlgHdr->resIDs[ii];
if ( 0 != id ) {
ceMoveItem( dlgHdr->hDlg, id, 0, distance );
}
}
#ifdef _WIN32_WCE
if ( IS_SMARTPHONE(dlgHdr->globals) ) {
SendMessage( dlgHdr->hDlg, DM_RESETSCROLL,
(WPARAM)FALSE, (LPARAM)TRUE );
}
#endif
} else {
XP_LOGF( "%s: resID %d not found", __func__, resID );
}
}
static void
setScrollPos( HWND hDlg, XP_S16 newPos )
{

View file

@ -51,6 +51,8 @@ int ceMessageBoxChar( CEAppGlobals* globals, const XP_UCHAR* str,
XP_Bool isUTF8, const wchar_t* title, XP_U16 buttons );
XP_Bool ceCurDictIsUTF8( CEAppGlobals* globals );
XP_U16 ceDistanceBetween( HWND hDlg, XP_U16 resID1, XP_U16 resID2 );
typedef enum {
PREFS_FILE_PATH_L
,DEFAULT_DIR_PATH_L
@ -69,17 +71,23 @@ typedef enum { DLG_STATE_NONE = 0
typedef struct CeDlgHdr {
CEAppGlobals* globals;
HWND hDlg;
/* set these two if will be calling ceDlgMoveBelow */
XP_U16* resIDs;
XP_U16 nResIDs;
/* Below this line is private to ceutil.c */
DlgStateTask doWhat;
XP_U16 nPage;
XP_U16 prevY;
XP_U16 nResIDsUsed;
XP_Bool penDown;
} CeDlgHdr;
void ceDlgSetup( CeDlgHdr* dlgHdr, HWND hDlg, DlgStateTask doWhat );
void ceDlgComboShowHide( CeDlgHdr* dlgHdr, XP_U16 baseId );
XP_Bool ceDoDlgHandle( CeDlgHdr* dlgHdr, UINT message, WPARAM wParam, LPARAM lParam);
void ceDlgMoveBelow( CeDlgHdr* dlgHdr, XP_U16 resID, XP_S16 distance );
/* Are we drawing things in landscape mode? */
XP_Bool ceIsLandscape( CEAppGlobals* globals );