#include "backendz.h"\r
\r
#define _(s) T_(s)\r
+#define N_(s) s\r
\r
int layoutList[2*MAX_OPTIONS];\r
int checkList[2*MAX_OPTIONS];\r
int groupNameList[2*MAX_OPTIONS];\r
int breaks[MAX_OPTIONS];\r
int checks, combos, buttons, layout, groups;\r
+char title[MSG_SIZ];\r
+char *engineName, *engineDir, *engineChoice, *engineLine, *nickName, *params;\r
+Boolean isUCI, hasBook, storeVariant, v1, addToList;\r
+extern Option installOptions[], matchOptions[];\r
+char *engineNr[] = { N_("First"), N_("Second"), NULL };\r
+char *engineList[1000] = {" "}, *engineMnemonic[1000] = {""};\r
+void (*okFunc)();\r
+ChessProgramState *activeCps;\r
+Option *activeList;\r
+void InstallOK P((void));\r
+typedef void ButtonCallback(HWND h);\r
\r
void\r
-PrintOpt(int i, int right, ChessProgramState *cps)\r
+PrintOpt(int i, int right, Option *optionList)\r
{\r
if(i<0) {\r
if(!right) fprintf(debugFP, "%30s", "");\r
} else {\r
- Option opt = cps->option[i];\r
+ Option opt = optionList[i];\r
switch(opt.type) {\r
case Slider:\r
case Spin:\r
case PathName:\r
fprintf(debugFP, "%20.20s [______________________________________]", opt.name);\r
break;\r
+ case Label:\r
+ fprintf(debugFP, "%41.41s", opt.name);\r
+ break;\r
case CheckBox:\r
fprintf(debugFP, "[x] %-26.25s", opt.name);\r
break;\r
}\r
\r
void\r
-CreateOptionDialogTest(int *list, int nr, ChessProgramState *cps)\r
+CreateOptionDialogTest(int *list, int nr, Option *optionList)\r
{\r
int line;\r
\r
for(line = 0; line < nr; line+=2) {\r
- PrintOpt(list[line+1], 0, cps);\r
- PrintOpt(list[line], 1, cps);\r
+ PrintOpt(list[line+1], 0, optionList);\r
+ PrintOpt(list[line], 1, optionList);\r
}\r
}\r
\r
case FileName:\r
case PathName:\r
case Slider:\r
+ case Label:\r
case Spin: stop++;\r
default:\r
case Message: ; // cannot happen\r
if(!stop)\r
nextType = Button; // kudge to flush remaining checks and combos undistorted\r
// Take a new line if a spin follows combos or checks, or when we encounter a textbox\r
- if((combos+checks || nextType == TextBox || nextType == FileName || nextType == PathName) && layout&1) {\r
+ if((combos+checks || nextType == TextBox || nextType == FileName || nextType == PathName || nextType == Label) && layout&1) {\r
layoutList[layout++] = -1;\r
}\r
// The last check or combo before a spin will be put on the same line as that spin (prefix)\r
layoutList[layout++] = -1;\r
layoutList[layout++] = comboList[2*right];\r
}\r
- if(nextType == TextBox || nextType == FileName || nextType == PathName) {\r
+ if(nextType == TextBox || nextType == FileName || nextType == PathName || nextType == Label) {\r
// A textBox is double width, so must be left-adjusted, and the right column remains empty\r
breaks[layout/2] = lastType == Button ? 0 : 100;\r
layoutList[layout++] = -1;\r
}\r
\r
void\r
-DesignOptionDialog(ChessProgramState *cps)\r
+DesignOptionDialog(int nrOpt, Option *optionList)\r
{\r
int k=0, n=0;\r
char buf[MSG_SIZ];\r
\r
layout = 0;\r
buttons = groups = 0;\r
- while(k < cps->nrOptions) { // k steps through 'solitary' options\r
+ while(k < nrOpt) { // k steps through 'solitary' options\r
// look if we hit a group of options having names that start with the same word\r
int groupSize = 1, groupNameLength = 50;\r
- sscanf(cps->option[k].name, "%s", buf); // get first word of option name\r
- while(k + groupSize < cps->nrOptions &&\r
- strstr(cps->option[k+groupSize].name, buf) == cps->option[k+groupSize].name) {\r
+ sscanf(optionList[k].name, "%s", buf); // get first word of option name\r
+ while(k + groupSize < nrOpt &&\r
+ strstr(optionList[k+groupSize].name, buf) == optionList[k+groupSize].name) {\r
int j;\r
for(j=0; j<groupNameLength; j++) // determine common initial part of option names\r
- if( cps->option[k].name[j] != cps->option[k+groupSize].name[j]) break;\r
+ if( optionList[k].name[j] != optionList[k+groupSize].name[j]) break;\r
groupNameLength = j;\r
groupSize++;\r
\r
}\r
if(groupSize > 3) {\r
// We found a group to terminates the current section\r
- LayoutOptions(n, k, "", cps->option); // flush all solitary options appearing before the group\r
+ LayoutOptions(n, k, "", optionList); // flush all solitary options appearing before the group\r
groupNameList[groups] = groupNameLength;\r
boxList[groups++] = layout; // group start in even entries\r
- LayoutOptions(k, k+groupSize, buf, cps->option); // flush the group\r
+ LayoutOptions(k, k+groupSize, buf, optionList); // flush the group\r
boxList[groups++] = layout; // group end in odd entries\r
k = n = k + groupSize;\r
} else k += groupSize; // small groups are grouped with the solitary options\r
}\r
- if(n != k) LayoutOptions(n, k, "", cps->option); // flush remaining solitary options\r
+ if(n != k) LayoutOptions(n, k, "", optionList); // flush remaining solitary options\r
// decide if and where we break into two column pairs\r
\r
// Emit buttons and add OK and cancel\r
// for(k=0; k<buttons; k++) layoutList[layout++] = buttonList[k];\r
- // Create the dialog window\r
- if(appData.debugMode) CreateOptionDialogTest(layoutList, layout, cps);\r
-// CreateOptionDialog(layoutList, layout, cps);\r
+ \r
+ // Create the dialog window\r
+ if(appData.debugMode) CreateOptionDialogTest(layoutList, layout, optionList);\r
+// CreateOptionDialog(layoutList, layout, optionList);\r
+ if(!activeCps) okFunc = optionList[nrOpt].target;\r
}\r
\r
#include <windows.h>\r
0x0000, 0x0000, L"Engine #1 Settings ", 8, L"MS Sans Serif"\r
};\r
\r
-ChessProgramState *activeCps;\r
-\r
void\r
-SetOptionValues(HWND hDlg, ChessProgramState *cps)\r
+SetOptionValues(HWND hDlg, ChessProgramState *cps, Option *optionList)\r
// Put all current option values in controls, and write option names next to them\r
{\r
HANDLE hwndCombo;\r
int i, k;\r
- char **choices, title[MSG_SIZ], *name;\r
+ char **choices, *name;\r
\r
for(i=0; i<layout+buttons; i++) {\r
int j=layoutList[i];\r
if(j == -2) SetDlgItemText( hDlg, 2000+2*i, ". . ." );\r
if(j<0) continue;\r
- name = cps->option[j].name;\r
+ name = optionList[j].name;\r
if(strstr(name, "Polyglot ") == name) name += 9;\r
SetDlgItemText( hDlg, 2000+2*i, name );\r
-//if(appData.debugMode) fprintf(debugFP, "# %s = %d\n",cps->option[j].name, cps->option[j].value );\r
- switch(cps->option[j].type) {\r
+//if(appData.debugMode) fprintf(debugFP, "# %s = %d\n",optionList[j].name, optionList[j].value );\r
+ switch(optionList[j].type) {\r
case Spin:\r
- SetDlgItemInt( hDlg, 2001+2*i, cps->option[j].value, TRUE );\r
+ SetDlgItemInt( hDlg, 2001+2*i, cps ? optionList[j].value : *(int*)optionList[j].target, TRUE );\r
break;\r
case TextBox:\r
case FileName:\r
case PathName:\r
- SetDlgItemText( hDlg, 2001+2*i, cps->option[j].textValue );\r
+ SetDlgItemText( hDlg, 2001+2*i, cps ? optionList[j].textValue : *(char**)optionList[j].target );\r
break;\r
case CheckBox:\r
- CheckDlgButton( hDlg, 2000+2*i, cps->option[j].value != 0);\r
+ CheckDlgButton( hDlg, 2000+2*i, (cps ? optionList[j].value : *(Boolean*)optionList[j].target) != 0);\r
break;\r
case ComboBox:\r
- choices = (char**) cps->option[j].textValue;\r
+ choices = (char**) optionList[j].textValue;\r
hwndCombo = GetDlgItem(hDlg, 2001+2*i);\r
SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
- for(k=0; k<cps->option[j].max; k++) {\r
+ for(k=0; k<optionList[j].max; k++) {\r
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) choices[k]);\r
}\r
- SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) choices[cps->option[j].value]);\r
+ SendMessage(hwndCombo, CB_SELECTSTRING, (WPARAM) -1, (LPARAM) choices[optionList[j].value]);\r
break;\r
case Button:\r
case SaveButton:\r
}\r
SetDlgItemText( hDlg, IDOK, _("OK") );\r
SetDlgItemText( hDlg, IDCANCEL, _("Cancel") );\r
- snprintf(title, MSG_SIZ, _("%s Engine Settings (%s)"), T_(cps->which), cps->tidy);\r
title[0] &= ~32; // capitalize\r
SetWindowText( hDlg, title);\r
for(i=0; i<groups; i+=2) {\r
id = k = boxList[i];\r
if(layoutList[k] < 0) k++;\r
if(layoutList[k] < 0) continue;\r
- for(p=0; p<groupNameList[i]; p++) buf[p] = cps->option[layoutList[k]].name[p];\r
+ for(p=0; p<groupNameList[i]; p++) buf[p] = optionList[layoutList[k]].name[p];\r
buf[p] = 0;\r
SetDlgItemText( hDlg, 2000+2*(id+MAX_OPTIONS), buf );\r
}\r
\r
\r
void\r
-GetOptionValues(HWND hDlg, ChessProgramState *cps)\r
+GetOptionValues(HWND hDlg, ChessProgramState *cps, Option *optionList)\r
// read out all controls, and if value is altered, remember it and send it to the engine\r
{\r
HANDLE hwndCombo;\r
for(i=0; i<layout; i++) {\r
int j=layoutList[i];\r
if(j<0) continue;\r
- switch(cps->option[j].type) {\r
+ switch(optionList[j].type) {\r
case Spin:\r
new = GetDlgItemInt( hDlg, 2001+2*i, &success, TRUE );\r
if(!success) break;\r
- if(new < cps->option[j].min) new = cps->option[j].min;\r
- if(new > cps->option[j].max) new = cps->option[j].max;\r
- changed = 2*(cps->option[j].value != new);\r
- cps->option[j].value = new;\r
+ if(new < optionList[j].min) new = optionList[j].min;\r
+ if(new > optionList[j].max) new = optionList[j].max;\r
+ if(!cps) { *(int*)optionList[j].target = new; break; }\r
+ changed = 2*(optionList[j].value != new);\r
+ optionList[j].value = new;\r
break;\r
case TextBox:\r
case FileName:\r
case PathName:\r
- success = GetDlgItemText( hDlg, 2001+2*i, newText, MSG_SIZ - strlen(cps->option[j].name) - 9 );\r
+ success = GetDlgItemText( hDlg, 2001+2*i, newText, MSG_SIZ - strlen(optionList[j].name) - 9 );\r
if(!success) break;\r
- changed = strcmp(cps->option[j].textValue, newText) != 0;\r
- safeStrCpy(cps->option[j].textValue, newText, MSG_SIZ - (cps->option[j].textValue - cps->option[j].name) );\r
+ if(!cps) {\r
+ if(*(char**)optionList[j].target) free(*(char**)optionList[j].target);\r
+ *(char**)optionList[j].target = strdup(newText);\r
+ break;\r
+ }\r
+ changed = strcmp(optionList[j].textValue, newText) != 0;\r
+ safeStrCpy(optionList[j].textValue, newText, MSG_SIZ - (optionList[j].textValue - optionList[j].name) );\r
break;\r
case CheckBox:\r
new = IsDlgButtonChecked( hDlg, 2000+2*i );\r
- changed = 2*(cps->option[j].value != new);\r
- cps->option[j].value = new;\r
+ if(!cps) { *(Boolean*)optionList[j].target = new; break; }\r
+ changed = 2*(optionList[j].value != new);\r
+ optionList[j].value = new;\r
break;\r
case ComboBox:\r
- choices = (char**) cps->option[j].textValue;\r
+ choices = (char**) optionList[j].textValue;\r
hwndCombo = GetDlgItem(hDlg, 2001+2*i);\r
success = GetDlgItemText( hDlg, 2001+2*i, newText, MSG_SIZ );\r
if(!success) break;\r
new = -1;\r
- for(k=0; k<cps->option[j].max; k++) {\r
+ for(k=0; k<optionList[j].max; k++) {\r
if(!strcmp(choices[k], newText)) new = k;\r
}\r
- changed = new >= 0 && (cps->option[j].value != new);\r
- if(changed) cps->option[j].value = new;\r
+ if(!cps && new) {\r
+ if(*(char**)optionList[j].target) free(*(char**)optionList[j].target);\r
+ *(char**)optionList[j].target = strdup(optionList[j].choice[new]);\r
+ break;\r
+ }\r
+ changed = new >= 0 && (optionList[j].value != new);\r
+ if(changed) optionList[j].value = new;\r
break;\r
case Button:\r
default:\r
break; // are treated instantly, so they have been sent already\r
}\r
if(changed == 2)\r
- snprintf(buf, MSG_SIZ, "option %s=%d\n", cps->option[j].name, new); else\r
+ snprintf(buf, MSG_SIZ, "option %s=%d\n", optionList[j].name, new); else\r
if(changed == 1)\r
- snprintf(buf, MSG_SIZ, "option %s=%s\n", cps->option[j].name, newText);\r
+ snprintf(buf, MSG_SIZ, "option %s=%s\n", optionList[j].name, newText);\r
if(changed) SendToProgram(buf, cps);\r
}\r
+ if(!cps && okFunc) ((ButtonCallback*) okFunc)(0);\r
}\r
\r
LRESULT CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
case WM_INITDIALOG:\r
\r
// CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
- SetOptionValues(hDlg, activeCps);\r
+ SetOptionValues(hDlg, activeCps, activeList);\r
\r
// SetFocus(GetDlgItem(hDlg, IDC_NFG_Edit));\r
\r
case WM_COMMAND:\r
switch( LOWORD(wParam) ) {\r
case IDOK:\r
- GetOptionValues(hDlg, activeCps);\r
+ GetOptionValues(hDlg, activeCps, activeList);\r
EndDialog( hDlg, 0 );\r
+ activeCps = NULL;\r
return TRUE;\r
\r
case IDCANCEL:\r
EndDialog( hDlg, 1 );\r
+ activeCps = NULL;\r
return TRUE;\r
\r
default:\r
}\r
}\r
if(j < 0) break;\r
- if( activeCps->option[j].type == SaveButton)\r
- GetOptionValues(hDlg, activeCps);\r
- else if( activeCps->option[j].type != Button) break;\r
- snprintf(buf, MSG_SIZ, "option %s\n", activeCps->option[j].name);\r
+ if( activeList[j].type == SaveButton)\r
+ GetOptionValues(hDlg, activeCps, activeList);\r
+ else if( activeList[j].type != Button) break;\r
+ snprintf(buf, MSG_SIZ, "option %s\n", activeList[j].name);\r
SendToProgram(buf, activeCps);\r
}\r
break;\r
break;\r
case TextBox:\r
AddControl(x, y+1, 95, 9, 0x0082, SS_ENDELLIPSIS | WS_VISIBLE | WS_CHILD, i);\r
- AddControl(x+95, y, 190, 11, 0x0081, ES_AUTOHSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i+1);\r
+ AddControl(x+95, y, 200, 11, 0x0081, ES_AUTOHSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i+1);\r
+ break;\r
+ case Label:\r
+ extra = activeList[layoutList[i/2]].value;\r
+ AddControl(x+extra, y+1, 290-extra, 9, 0x0082, SS_ENDELLIPSIS | WS_VISIBLE | WS_CHILD, i);\r
break;\r
case FileName:\r
case PathName:\r
break;\r
case ComboBox:\r
AddControl(x, y+1, 95, 9, 0x0082, SS_ENDELLIPSIS | WS_VISIBLE | WS_CHILD, i);\r
- AddControl(x+95, y-1, 50, 500, 0x0085, CBS_AUTOHSCROLL | CBS_DROPDOWN | WS_VISIBLE | WS_CHILD | WS_TABSTOP, i+1);\r
+ AddControl(x+95, y-1, !activeCps && x<10 ? 120 : 50, 500, 0x0085,\r
+ CBS_AUTOHSCROLL | CBS_DROPDOWN | WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL, i+1);\r
break;\r
case Button:\r
case ResetButton:\r
}\r
\r
void\r
-CreateDialogTemplate(int *layoutList, int nr, ChessProgramState *cps)\r
+CreateDialogTemplate(int *layoutList, int nr, Option *optionList)\r
{\r
int i, j, x=1, y=0, buttonRows, breakPoint = -1, k=0;\r
\r
}\r
j = layoutList[i];\r
if(j >= 0)\r
- AddOption(x+155-150*(i&1), y+13*(i>>1)+5, cps->option[j].type, 2*i);\r
+ AddOption(x+155-150*(i&1), y+13*(i>>1)+5, optionList[j].type, 2*i);\r
if(k < groups && i+1 == boxList[k+1]) {\r
k += 2; y += 4;\r
}\r
AddControl(x+70*(i%4)+5, y+18*(i/4), 65, 15, 0x0080, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, 2*(nr+i));\r
layoutList[nr+i] = buttonList[i];\r
}\r
- template.title[8] = cps == &first ? '1' : '2';\r
+ template.title[8] = optionList == first.option ? '1' : '2';\r
template.header.cy = y += 18*buttonRows+2;\r
template.header.style &= ~WS_VSCROLL;\r
}\r
{\r
FARPROC lpProc = MakeProcInstance( (FARPROC) SettingsProc, hInst );\r
\r
- activeCps = cps;\r
- DesignOptionDialog(cps);\r
- CreateDialogTemplate(layoutList, layout, cps);\r
+ activeCps = cps; activeList = cps->option;\r
+ snprintf(title, MSG_SIZ, _("%s Engine Settings (%s)"), T_(cps->which), cps->tidy);\r
+ DesignOptionDialog(cps->nrOptions, cps->option);\r
+ CreateDialogTemplate(layoutList, layout, cps->option);\r
\r
\r
DialogBoxIndirect( hInst, &template.header, hwnd, (DLGPROC)lpProc );\r
return;\r
}\r
\r
+void InstallOK()\r
+{\r
+ if(engineChoice[0] == engineNr[0][0]) Load(&first, 0); else Load(&second, 1);\r
+}\r
\r
+Option installOptions[] = {\r
+ { 0, 0, 0, NULL, (void*) &engineLine, (char*) engineMnemonic, engineList, ComboBox, N_("Select engine from list:") },\r
+ { 0, 0, 0, NULL, NULL, NULL, NULL, Label, N_("or specify one below:") },\r
+ { 0, 0, 0, NULL, (void*) &nickName, NULL, NULL, TextBox, N_("Nickname (optional):") },\r
+ { 0, 0, 3, NULL, (void*) &engineName, NULL, NULL, FileName, N_("Engine Executable:") },\r
+ { 0, 0, 0, NULL, (void*) ¶ms, NULL, NULL, TextBox, N_("Engine command-line Parameters:") },\r
+ { 0, 0, 0, NULL, (void*) &engineDir, NULL, NULL, PathName, N_("Engine Directory:") },\r
+ { 95, 0, 0, NULL, NULL, NULL, NULL, Label, N_("(Directory will be derived from engine path when empty)") },\r
+ { 0, 0, 0, NULL, (void*) &isUCI, NULL, NULL, CheckBox, N_("UCI") },\r
+ { 0, 0, 0, NULL, (void*) &v1, NULL, NULL, CheckBox, N_("WB protocol v1 (skip waiting for features)") },\r
+ { 0, 0, 0, NULL, (void*) &addToList, NULL, NULL, CheckBox, N_("Add this engine to the list") },\r
+ { 0, 0, 0, NULL, (void*) &hasBook, NULL, NULL, CheckBox, N_("Must not use GUI book") },\r
+ { 0, 0, 0, NULL, (void*) &storeVariant, NULL, NULL, CheckBox, N_("Force current variant with this engine") },\r
+ { 0, 0, 2, NULL, (void*) &engineChoice, (char*) engineNr, engineNr, ComboBox, N_("Load mentioned engine as") },\r
+ { 0, 1, 0, NULL, (void*) &InstallOK, "", NULL, EndMark , "" }\r
+};\r
+\r
+void\r
+GenericPopup(HWND hwnd, Option *optionList)\r
+{\r
+ FARPROC lpProc = MakeProcInstance( (FARPROC) SettingsProc, hInst );\r
+ int n=0;\r
+\r
+ while(optionList[n].type != EndMark) n++;\r
+ activeCps = NULL; activeList = optionList;\r
+ DesignOptionDialog(n, optionList);\r
+ CreateDialogTemplate(layoutList, layout, optionList);\r
+\r
+ DialogBoxIndirect( hInst, &template.header, hwnd, (DLGPROC)lpProc );\r
+\r
+ FreeProcInstance(lpProc);\r
+\r
+ return;\r
+}\r
+\r
+void LoadEnginePopUp(HWND hwnd)\r
+{\r
+ int n=0;\r
+\r
+ isUCI = addToList = storeVariant = v1 = FALSE; hasBook = TRUE; // defaults\r
+ if(engineDir) free(engineDir); engineDir = strdup("");\r
+ if(params) free(params); params = strdup("");\r
+ if(nickName) free(nickName); nickName = strdup("");\r
+ if(engineChoice) free(engineChoice); engineChoice = strdup(engineNr[0]);\r
+ if(engineLine) free(engineLine); engineLine = strdup("");\r
+ NamesToList(firstChessProgramNames, engineList, engineMnemonic);\r
+ while(engineList[n]) n++; installOptions[0].max = n;\r
+ snprintf(title, MSG_SIZ, _("Load Engine"));\r
+\r
+ GenericPopup(hwnd, installOptions);\r
+}\r