Redesign WinBoard Load Engine dialog
authorH.G.Muller <hgm@hgm-xboard.(none)>
Mon, 30 Oct 2017 17:11:24 +0000 (18:11 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Mon, 30 Oct 2017 19:27:30 +0000 (20:27 +0100)
The checkboxes for protocol choice are replaced by a combobox, which
also contains an autodetect option. This is encoded through the kludge
of setting isUCI = 3.
 The fields that do not usually have to be specified are now put in
group boxes, which make it more clear the user can ignore them.
For this a ew control type GroupBox had to be defined, and supported
in the GenericPopup.

backend.c
backend.h
winboard/wsettings.c

index e5c7f72..7358f4a 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -1060,13 +1060,13 @@ Load (ChessProgramState *cps, int i)
     }
     if(jar) { snprintf(buf3, MSG_SIZ, "java -jar %s", p); p = buf3; }
     ASSIGN(appData.chessProgram[i], p);
+    if(isUCI == 3) tryNr = 1, isUCI = 0; // auto-detect
     appData.isUCI[i] = isUCI;
     appData.protocolVersion[i] = v1 ? 1 : PROTOVER;
     appData.hasOwnBookUCI[i] = hasBook;
     if(!nickName[0]) useNick = FALSE;
     if(useNick) ASSIGN(appData.pgnName[i], nickName);
     safeStrCpy(newEngineCommand, p, MSG_SIZ);
-    tryNr = 1;
     ReplaceEngine(cps, i);
 }
 
index befa893..2fbae11 100644 (file)
--- a/backend.h
+++ b/backend.h
@@ -297,7 +297,7 @@ int Explode P((Board board, int fromX, int fromY, int toX, int toY));
 
 typedef enum { CheckBox, ComboBox, TextBox, Button, Spin, ResetButton, SaveButton, ListBox, Graph, PopUp,
                 FileName, PathName, Slider, Message, Fractional, Label, Icon,
-                BoxBegin, BoxEnd, BarBegin, BarEnd, DropDown, Break, EndMark, Skip } Control;
+                BoxBegin, BoxEnd, BarBegin, BarEnd, DropDown, Break, GroupBox, EndMark, Skip } Control;
 
 typedef struct XB_OPT {   // [HGM] options: descriptor of UCI-style option
     int value;          // current setting, starts as default
index 04957e7..b65566c 100644 (file)
@@ -57,7 +57,7 @@ int groupNameList[2*MAX_OPTIONS];
 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
+char *engineName, *engineDir, *protocolChoice, *engineLine, *nickName, *params;\r
 Boolean isUCI, hasBook, storeVariant, v1, addToList, useNick, isUCCI;\r
 extern Option installOptions[], matchOptions[];\r
 char *engineList[MAXENGINES] = {""}, *engineMnemonic[MAXENGINES] = {""};\r
@@ -141,6 +141,7 @@ LayoutOptions(int firstOption, int endOption, char *groupName, Option *optionLis
                case PathName:\r
                case Slider:\r
                case Label:\r
+               case GroupBox:\r
                case Spin: stop++;\r
                default:\r
                case Message: ; // cannot happen\r
@@ -241,6 +242,7 @@ DesignOptionDialog(int nrOpt, Option *optionList)
        // look if we hit a group of options having names that start with the same word\r
        int groupSize = 1, groupNameLength = 50;\r
        sscanf(optionList[k].name, "%s", buf); // get first word of option name\r
+       if(optionList[k].type == GroupBox) groupSize = optionList[k].max, groupNameLength = -strlen(optionList[k].name), groupNameList[groups+1] = k; else\r
        while(k + groupSize < nrOpt &&\r
              strstr(optionList[k+groupSize].name, buf) == optionList[k+groupSize].name) {\r
                int j;\r
@@ -255,6 +257,7 @@ DesignOptionDialog(int nrOpt, Option *optionList)
                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
+               if(groupNameLength <= 0) n = ++k;\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
@@ -372,6 +375,7 @@ SetOptionValues(HWND hDlg, ChessProgramState *cps, Option *optionList)
        if(layoutList[k] < 0) continue;\r
        for(p=0; p<groupNameList[i]; p++) buf[p] = optionList[layoutList[k]].name[p];\r
        buf[p] = 0;\r
+       if(groupNameList[i] < 0) safeStrCpy(buf, optionList[groupNameList[i+1]].name, MSG_SIZ);\r
        SetDlgItemText( hDlg, 2000+2*(id+MAX_OPTIONS), buf );\r
     }\r
 }\r
@@ -430,7 +434,7 @@ GetOptionValues(HWND hDlg, ChessProgramState *cps, Option *optionList)
                for(k=0; k<optionList[j].max; k++) {\r
                    if(choices[k] && !strcmp(choices[k], newText)) new = k;\r
                }\r
-               if(!cps && new > 0) {\r
+               if(!cps && new >= 0) {\r
                    if(*(char**)optionList[j].target) free(*(char**)optionList[j].target);\r
                    *(char**)optionList[j].target = strdup(optionList[j].choice[new]);\r
                    break;\r
@@ -640,7 +644,7 @@ CreateDialogTemplate(int *layoutList, int nr, Option *optionList)
     template.header.cdit = 0;\r
     template.header.cx = 307;\r
     buttonRows = (buttons + 1 + 3)/4; // 4 per row, rounded up\r
-    if(nr > 50) {\r
+    if(nr > 48) {\r
        breakPoint = (nr+2*buttonRows+1)/2 & ~1;\r
        template.header.cx = 625;\r
     }\r
@@ -648,10 +652,11 @@ CreateDialogTemplate(int *layoutList, int nr, Option *optionList)
     for(ii=0; ii<nr; ii++) {\r
        i = ii^1; if(i == nr) i = ii; // if two on one line, swap order of treatment, to get good (left to right) tabbing order.\r
        if(k < groups && ii == boxList[k]) {\r
+           int tlen = groupNameList[k]; if(tlen < 0) tlen = -tlen;\r
            y += 10;\r
            AddControl(x+2, y+13*(i>>1)-2, 301, 13*(boxList[k+1]-boxList[k]>>1)+8,\r
                                                0x0082, WS_VISIBLE | WS_CHILD | SS_BLACKFRAME, 2400);\r
-           AddControl(x+60, y+13*(i>>1)-6, 10*groupNameList[k]/3, 10,\r
+           AddControl(x+60, y+13*(i>>1)-6, 10*tlen/3, 10,\r
                                                0x0082, SS_ENDELLIPSIS | WS_VISIBLE | WS_CHILD, 2*(ii+MAX_OPTIONS));\r
        }\r
        j = layoutList[i];\r
@@ -715,11 +720,16 @@ RefreshSettingsDialog (ChessProgramState *cps, int val)
 int EnterGroup P((HWND hDlg));\r
 \r
 static int engineNr, selected;\r
+char *protocols[] = { "autodetect", "WB", "UCI", "USI/UCCI", "WB v1", NULL };\r
 \r
 int InstallOK()\r
 {\r
     if(selected >= 0) { ASSIGN(engineLine, engineList[selected]); }\r
     if(engineLine[0] == '#') { DisplayError(_("Select single engine from the group"), 0); return 0; }\r
+    if(!strcmp(protocolChoice, protocols[0])) isUCI = 3; else\r
+    if(!strcmp(protocolChoice, protocols[2])) isUCI = 1; else\r
+    if(!strcmp(protocolChoice, protocols[3])) isUCCI = 1; else\r
+    if(!strcmp(protocolChoice, protocols[4])) v1 = 1;\r
     if(isUCCI) isUCI = 2;\r
     if(!engineNr) Load(&first, 0); else Load(&second, 1);\r
     return 1;\r
@@ -729,19 +739,19 @@ Option installOptions[] = {
 //  {   0,  0,    0, NULL, (void*) &engineLine, (char*) engineMnemonic, engineList, ComboBox, N_("Select engine from list:") },\r
   { 195, 14,    0, NULL, (void*) &EnterGroup, (char*) &selected, engineMnemonic, ListBox, N_("Select engine from list:") },\r
   {   0,  0,    0, NULL, NULL, NULL, NULL, Label, N_("or specify one below:") },\r
+  {   0,  0, 32+3, NULL, (void*) &engineName, NULL, NULL, FileName, N_("Engine (.exe or .jar):") },\r
+  {   0,  0,    5, NULL, (void*) &protocolChoice, (char*) protocols, protocols, ComboBox, N_("Engine protocol") },\r
+  {   0,  0,    5, NULL, NULL, NULL, NULL, GroupBox, N_("Optional user preferences") },\r
   {   0,  0,    0, NULL, (void*) &nickName, NULL, NULL, TextBox, N_("Nickname (optional):") },\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*) &useNick, NULL, NULL, CheckBox, N_("Use nickname in PGN tag") },\r
-  {   0,  0, 32+3, NULL, (void*) &engineName, NULL, NULL, FileName, N_("Engine (.exe or .jar):") },\r
+  {   0,  0,    0, NULL, (void*) &storeVariant, NULL, NULL, CheckBox, N_("Force current variant with this engine") },\r
+  {   0,  0,    4, NULL, NULL, NULL, NULL, GroupBox, N_("Advanced (special cases only, as per engine README file)") },\r
   {   0,  0,    0, NULL, (void*) &params, NULL, NULL, TextBox, N_("command-line parameters:") },\r
   {   0,  0,    0, NULL, (void*) &wbOptions, NULL, NULL, TextBox, N_("Special WinBoard options:") },\r
   {   0,  0,    0, NULL, (void*) &engineDir, NULL, NULL, PathName, N_("directory:") },\r
   {  95,  0,    0, NULL, NULL, NULL, NULL, Label, N_("(Directory will be derived from engine path when left empty)") },\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,    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*) &isUCCI, NULL, NULL, CheckBox, N_("UCCI/USI/Arena960 (through /uxiAdapter)") },\r
   {   0,  1,    0, NULL, (void*) &InstallOK, "", NULL, EndMark , "" }\r
 };\r
 \r
@@ -790,7 +800,6 @@ EnterGroup(HWND hDlg)
 \r
 void LoadEnginePopUp(HWND hwnd, int nr)\r
 {\r
-    if(*engineListFile) ParseSettingsFile(engineListFile, &engineListFile); // contains engine list\r
     isUCI = isUCCI = storeVariant = v1 = useNick = FALSE; addToList = hasBook = TRUE; // defaults\r
     engineNr = nr;\r
     if(engineDir)    free(engineDir);    engineDir = strdup("");\r