xwords/xwords4/wince/ceprefs.c

348 lines
12 KiB
C
Executable file

/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
/*
* Copyright 2002 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include "ceprefs.h"
#include "cemain.h"
#include "ceclrsel.h"
#include "ceutil.h"
#include "debhacks.h"
#include "cedebug.h"
/* Stuff the strings for phonies. Why can't I put this in the resource?
*/
static void
stuffPhoniesList( HWND hDlg )
{
XP_U16 i;
wchar_t* strings[] = {
L"Ignore",
L"Warn",
L"Disallow"
};
for ( i = 0; i < 3; ++i ) {
SendDlgItemMessage( hDlg, PHONIES_COMBO, ADDSTRING,
0, (long)strings[i] );
}
} /* stuffPhoniesList */
static void
turnOnOff( HWND hDlg, XP_U16* idList, XP_U16 idCount,
XP_Bool turnOn )
{
XP_U16 i;
for ( i = 0; i < idCount; ++i ) {
ceShowOrHide( hDlg, *idList++, turnOn );
}
} /* turnOff */
static void
setTimerCtls( HWND hDlg, XP_Bool checked )
{
ceShowOrHide( hDlg, TIMER_EDIT, checked );
SendDlgItemMessage( hDlg, TIMER_CHECK, BM_SETCHECK,
checked? BST_CHECKED:BST_UNCHECKED, 0 );
} /* setTimerCtls */
static void
adjustForChoice( HWND hDlg, CePrefsDlgState* state )
{
XP_U16 goesWithGlobal[] = {IDC_CHECKCOLORPLAYED, IDC_LEFTYCHECK,
IDC_CHECKSHOWCURSOR, IDC_CHECKROBOTSCORES,
IDC_PREFCOLORS };
XP_U16 goesWithLocal[] = {IDC_CHECKSMARTROBOT, IDC_CHECKNOHINTS,
TIMER_CHECK, TIMER_EDIT, PHONIES_LABEL,
PHONIES_COMBO, IDC_PHONIESUPDOWN, IDC_PICKTILES
#ifdef XWFEATURE_SEARCHLIMIT
,IDC_CHECKHINTSLIMITS
#endif
};
XP_U16 resID;
XP_Bool doGlobalPrefs = state->globals->doGlobalPrefs;
resID = doGlobalPrefs? IDC_RADIOGLOBAL:IDC_RADIOLOCAL;
SendDlgItemMessage( hDlg, resID, BM_SETCHECK, BST_CHECKED, 0L );
if ( doGlobalPrefs ) {
turnOnOff( hDlg, goesWithLocal, VSIZE(goesWithLocal), XP_FALSE );
turnOnOff( hDlg, goesWithGlobal, VSIZE(goesWithGlobal), XP_TRUE);
} else {
turnOnOff( hDlg, goesWithGlobal, VSIZE(goesWithGlobal), XP_FALSE );
turnOnOff( hDlg, goesWithLocal, VSIZE(goesWithLocal), XP_TRUE);
}
if ( !doGlobalPrefs ) {
setTimerCtls( hDlg, ceGetChecked( hDlg, TIMER_CHECK ) );
#ifdef XWFEATURE_SEARCHLIMIT
ceShowOrHide( hDlg, IDC_CHECKHINTSLIMITS,
!ceGetChecked( hDlg, IDC_CHECKNOHINTS) );
#endif
}
} /* adjustForChoice */
/* Copy global state into a local copy that can be changed without
* committing should user cancel.
*/
void
loadStateFromCurPrefs( CEAppGlobals* XP_UNUSED_STANDALONE(globals),
const CEAppPrefs* appPrefs,
const CurGameInfo* gi, CePrefsPrefs* prefsPrefs )
{
prefsPrefs->gp.hintsNotAllowed = gi->hintsNotAllowed;
prefsPrefs->gp.robotSmartness = gi->robotSmartness;
prefsPrefs->gp.timerEnabled = gi->timerEnabled;
prefsPrefs->gp.gameSeconds = gi->gameSeconds;
prefsPrefs->gp.phoniesAction = gi->phoniesAction;
#ifdef FEATURE_TRAY_EDIT
prefsPrefs->gp.allowPickTiles = gi->allowPickTiles;
#endif
#ifdef XWFEATURE_SEARCHLIMIT
prefsPrefs->gp.allowHintRect = gi->allowHintRect;
#endif
prefsPrefs->showColors = appPrefs->showColors;
XP_MEMCPY( &prefsPrefs->cp, &appPrefs->cp, sizeof(prefsPrefs->cp) );
XP_MEMCPY( &prefsPrefs->colors, &appPrefs->colors,
sizeof(prefsPrefs->colors) );
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
if ( globals->game.comms != NULL ) {
comms_getAddr( globals->game.comms, &prefsPrefs->addrRec );
} else {
comms_getInitialAddr( &prefsPrefs->addrRec );
}
#endif
} /* loadStateFromCurPrefs */
void
loadCurPrefsFromState( CEAppGlobals* XP_UNUSED_STANDALONE(globals),
CEAppPrefs* appPrefs,
CurGameInfo* gi, const CePrefsPrefs* prefsPrefs )
{
gi->hintsNotAllowed = prefsPrefs->gp.hintsNotAllowed;
gi->robotSmartness = prefsPrefs->gp.robotSmartness;
gi->timerEnabled = prefsPrefs->gp.timerEnabled;
gi->gameSeconds = prefsPrefs->gp.gameSeconds;
gi->phoniesAction = prefsPrefs->gp.phoniesAction;
#ifdef FEATURE_TRAY_EDIT
gi->allowPickTiles = prefsPrefs->gp.allowPickTiles;
#endif
#ifdef XWFEATURE_SEARCHLIMIT
gi->allowHintRect = prefsPrefs->gp.allowHintRect;
#endif
appPrefs->showColors = prefsPrefs->showColors;
XP_MEMCPY( &appPrefs->cp, &prefsPrefs->cp, sizeof(appPrefs->cp) );
XP_MEMCPY( &appPrefs->colors, &prefsPrefs->colors,
sizeof(prefsPrefs->colors) );
#ifndef XWFEATURE_STANDALONE_ONLY
/* I don't think this'll work... */
if ( globals->game.comms != NULL ) {
comms_setAddr( globals->game.comms, &prefsPrefs->addrRec );
} else {
XP_LOGF( "no comms to set addr on!!!" );
}
#endif
} /* loadCurPrefsFromState */
/* Reflect local state into the controls user will see.
*/
static void
loadControlsFromState( HWND hDlg, CePrefsDlgState* pState )
{
CePrefsPrefs* prefsPrefs = &pState->prefsPrefs;
ceSetChecked( hDlg, IDC_CHECKCOLORPLAYED, prefsPrefs->showColors );
ceSetChecked( hDlg, IDC_CHECKSMARTROBOT,
prefsPrefs->gp.robotSmartness > 0 );
ceSetChecked( hDlg, IDC_CHECKNOHINTS, prefsPrefs->gp.hintsNotAllowed );
ceSetChecked( hDlg, IDC_CHECKSHOWCURSOR, prefsPrefs->cp.showBoardArrow );
ceSetChecked( hDlg, IDC_CHECKROBOTSCORES, prefsPrefs->cp.showRobotScores );
#ifdef FEATURE_TRAY_EDIT
ceSetChecked( hDlg, IDC_PICKTILES, prefsPrefs->gp.allowPickTiles );
#endif
#ifdef XWFEATURE_SEARCHLIMIT
ceSetChecked( hDlg, IDC_CHECKHINTSLIMITS, prefsPrefs->gp.allowHintRect );
#endif
/* timer */
ceSetDlgItemNum( hDlg, TIMER_EDIT, prefsPrefs->gp.gameSeconds / 60 );
SendDlgItemMessage( hDlg, PHONIES_COMBO, SETCURSEL,
prefsPrefs->gp.phoniesAction, 0L );
if ( !pState->isNewGame ) {
XP_U16 unavail[] = { TIMER_CHECK, TIMER_EDIT, IDC_CHECKNOHINTS
#ifdef FEATURE_TRAY_EDIT
,IDC_PICKTILES
#endif
};
XP_U16 i;
for ( i = 0; i < VSIZE(unavail); ++i ) {
ceEnOrDisable( hDlg, unavail[i], XP_FALSE );
}
}
} /* loadControlsFromState */
/* Save the new choices into state so caller can do what it wants with
* the values.
*/
static void
ceControlsToPrefs( HWND hDlg, CePrefsPrefs* prefsPrefs )
{
XP_S16 selIndex;
prefsPrefs->showColors = ceGetChecked( hDlg, IDC_CHECKCOLORPLAYED );
prefsPrefs->gp.robotSmartness
= ceGetChecked( hDlg, IDC_CHECKSMARTROBOT ) ? 1 : 0;
prefsPrefs->gp.hintsNotAllowed = ceGetChecked( hDlg, IDC_CHECKNOHINTS );
selIndex = (XP_U16)SendDlgItemMessage( hDlg, PHONIES_COMBO, GETCURSEL,
0, 0 );
if ( selIndex != LB_ERR ) {
prefsPrefs->gp.phoniesAction = (XWPhoniesChoice)selIndex;
}
prefsPrefs->cp.showBoardArrow = ceGetChecked( hDlg, IDC_CHECKSHOWCURSOR );
prefsPrefs->cp.showRobotScores = ceGetChecked( hDlg, IDC_CHECKROBOTSCORES );
prefsPrefs->gp.timerEnabled = ceGetChecked( hDlg, TIMER_CHECK );
if ( prefsPrefs->gp.timerEnabled ) {
XP_U16 minutes;
minutes = ceGetDlgItemNum( hDlg, TIMER_EDIT );
prefsPrefs->gp.gameSeconds = minutes * 60;
}
#ifdef FEATURE_TRAY_EDIT
prefsPrefs->gp.allowPickTiles = ceGetChecked( hDlg, IDC_PICKTILES );
#endif
#ifdef XWFEATURE_SEARCHLIMIT
prefsPrefs->gp.allowHintRect = ceGetChecked( hDlg, IDC_CHECKHINTSLIMITS );
#endif
} /* ceControlsToPrefs */
LRESULT CALLBACK
PrefsDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
CEAppGlobals* globals;
XP_U16 id;
CePrefsDlgState* pState;
if ( message == WM_INITDIALOG ) {
SetWindowLong( hDlg, GWL_USERDATA, lParam );
pState = (CePrefsDlgState*)lParam;
globals = pState->globals;
stuffPhoniesList( hDlg );
loadControlsFromState( hDlg, pState );
adjustForChoice( hDlg, pState );
ceDlgSetup( globals, hDlg, XP_TRUE );
return TRUE;
} else {
XP_Bool timerOn;
pState = (CePrefsDlgState*)GetWindowLong( hDlg, GWL_USERDATA );
if ( !!pState ) {
globals = pState->globals;
switch (message) {
case WM_VSCROLL:
if ( !IS_SMARTPHONE(globals) ) {
ceDoDlgScroll( globals, hDlg, wParam );
}
break;
case WM_COMMAND:
if ( !IS_SMARTPHONE(globals) ) {
ceDoDlgFocusScroll( globals, hDlg );
}
id = LOWORD(wParam);
switch( id ) {
case IDC_RADIOGLOBAL:
case IDC_RADIOLOCAL:
pState->globals->doGlobalPrefs = id == IDC_RADIOGLOBAL;
adjustForChoice( hDlg, pState );
break;
case TIMER_CHECK:
timerOn = SendDlgItemMessage( hDlg, TIMER_CHECK, BM_GETCHECK,
0, 0 );
setTimerCtls( hDlg, timerOn );
break;
case IDC_PREFCOLORS:
pState->colorsChanged =
ceDoColorsEdit( hDlg, pState->globals,
pState->prefsPrefs.colors );
break;
#ifdef XWFEATURE_SEARCHLIMIT
case IDC_CHECKNOHINTS:
timerOn = SendDlgItemMessage( hDlg, IDC_CHECKNOHINTS,
BM_GETCHECK, 0, 0 );
ceShowOrHide( hDlg, IDC_CHECKHINTSLIMITS, !timerOn );
break;
#endif
case IDOK:
ceControlsToPrefs( hDlg, &pState->prefsPrefs );
case IDCANCEL:
EndDialog(hDlg, id);
pState->userCancelled = id == IDCANCEL;
return TRUE;
}
}
}
}
return FALSE;
} /* PrefsDlg */
/* Using state in prefsPrefs, and initing and then storing dialog state in
state, put up the dialog and return whether it was cancelled.
*/
XP_Bool
WrapPrefsDialog( HWND hDlg, CEAppGlobals* globals, CePrefsDlgState* state,
CePrefsPrefs* prefsPrefs, XP_Bool isNewGame )
{
XP_Bool result;
XP_MEMSET( state, 0, sizeof(*state) );
state->globals = globals;
state->isNewGame = isNewGame;
XP_MEMCPY( &state->prefsPrefs, prefsPrefs, sizeof( state->prefsPrefs ) );
DialogBoxParam( globals->hInst, (LPCTSTR)IDD_OPTIONSDLG, hDlg,
(DLGPROC)PrefsDlg, (long)state );
result = !state->userCancelled;
if ( result ) {
XP_MEMCPY( prefsPrefs, &state->prefsPrefs, sizeof( *prefsPrefs ) );
}
return result;
} /* WrapPrefsDialog */