mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-26 09:58:20 +01:00
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:
parent
1929505c10
commit
0d326c0252
3 changed files with 202 additions and 48 deletions
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
Loading…
Reference in a new issue