Redesign New Variant dialog of WinBoard
authorH.G.Muller <hgm@hgm-xboard.(none)>
Tue, 5 Jul 2022 11:58:19 +0000 (13:58 +0200)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Tue, 5 Jul 2022 11:58:19 +0000 (13:58 +0200)
Because of the large number of engine-defined variants supported
by some engines, radiobuttons are no longer a suitable interface
for selecting the variant. These are now replaced by a single combobox,
which is filled with all standard variants in -ncp mode, and with
all variants (standard or engine-defined) supported by the first engine
if an engine is loaded.

winboard/winboard.rc
winboard/woptions.c

index 1b22a52..810bb12 100644 (file)
@@ -711,101 +711,20 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Variants"\r
 FONT 8, "MS Sans Serif"\r
 BEGIN\r
-    CONTROL         "&normal",OPT_VariantNormal,"Button",BS_AUTORADIOBUTTON | \r
-                    WS_GROUP,9,14,70,10\r
-    CONTROL         "&FRC",OPT_VariantFRC,"Button",BS_AUTORADIOBUTTON,9,\r
-                    24,70,10\r
-    CONTROL         "&wildcastle",OPT_VariantWildcastle,"Button",BS_AUTORADIOBUTTON,9,34,\r
-                    50,10\r
-    CONTROL         "&nocastle",OPT_VariantNocastle,"Button",BS_AUTORADIOBUTTON,9,\r
-                    44,70,10\r
-    CONTROL         "&losers",OPT_VariantLosers,"Button",BS_AUTORADIOBUTTON,\r
-                    9,54,70,10\r
-    CONTROL         "&giveaway",OPT_VariantGiveaway,"Button",BS_AUTORADIOBUTTON,\r
-                    9,64,70,10\r
-    CONTROL         "s&uicide",OPT_VariantSuicide,"Button",BS_AUTORADIOBUTTON,\r
-                    9,74,70,10\r
-    CONTROL         "&3Check",OPT_Variant3Check,"Button",BS_AUTORADIOBUTTON,9,84,\r
-                    70,10\r
-    CONTROL         "&twokings",OPT_VariantTwoKings,"Button",BS_AUTORADIOBUTTON,9,94,\r
-                    70,10\r
-    CONTROL         "&atomic",OPT_VariantAtomic,"Button",BS_AUTORADIOBUTTON,\r
-                    9,104,70,10\r
-    CONTROL         "&Mighty Lion",OPT_VariantLion,"Button",BS_AUTORADIOBUTTON,\r
-                    9,114,70,10\r
-    CONTROL         "cra&zyhouse",OPT_VariantCrazyhouse,"Button",BS_AUTORADIOBUTTON,80,14,\r
-                    70,10\r
-    CONTROL         "&bughouse",OPT_VariantBughouse,"Button",BS_AUTORADIOBUTTON,80,24,70,\r
-                    10\r
-    CONTROL         "Sp&artan",OPT_VariantSpartan,"Button",BS_AUTORADIOBUTTON,80,34,70,\r
-                    10\r
-    CONTROL         "&shogi",OPT_VariantShogi,"Button",BS_AUTORADIOBUTTON,80,\r
-                    44,70,10\r
-    CONTROL         "su&per",OPT_VariantSuper,"Button",BS_AUTORADIOBUTTON,80,\r
-                    54,70,10\r
-    CONTROL         "&knightmate",OPT_VariantKnightmate,"Button",BS_AUTORADIOBUTTON,\r
-                    80,64,70,10\r
-    CONTROL         "&Berolina",OPT_VariantBerolina,"Button",BS_AUTORADIOBUTTON,80,74,\r
-                    70,10\r
-    CONTROL         "c&ylinder",OPT_VariantCylinder,"Button",BS_AUTORADIOBUTTON,80,\r
-                    84,70,10\r
-    CONTROL         "&fairy",OPT_VariantFairy,"Button",BS_AUTORADIOBUTTON,80,\r
-                    94,70,10\r
-    CONTROL         "&makruk",OPT_VariantMakruk,"Button",BS_AUTORADIOBUTTON,80,\r
-                    104,70,10\r
-    CONTROL         "&ASEAN",OPT_VariantASEAN,"Button",BS_AUTORADIOBUTTON,80,\r
-                    114,70,10\r
-    CONTROL         "&gothic",OPT_VariantGothic,"Button",BS_AUTORADIOBUTTON,154,14,\r
-                    70,10\r
-    CONTROL         "&capablanca",OPT_VariantCapablanca,"Button",BS_AUTORADIOBUTTON,154,\r
-                    24,70,10\r
-    CONTROL         "&Janus",OPT_VariantJanus,"Button",BS_AUTORADIOBUTTON,154,34,\r
-                    70,10\r
-    CONTROL         "&CRC",OPT_VariantCRC,"Button",BS_AUTORADIOBUTTON,154,44,\r
-                    70,10\r
-    CONTROL         "&Falcon",OPT_VariantFalcon,"Button",BS_AUTORADIOBUTTON,154,\r
-                    54,70,10\r
-    CONTROL         "cou&rier",OPT_VariantCourier,"Button",BS_AUTORADIOBUTTON,154,64,\r
-                    70,10\r
-    CONTROL         "&Great",OPT_VariantGreat,"Button",BS_AUTORADIOBUTTON,154,74,\r
-                    70,10\r
-    CONTROL         "&Shatranj",OPT_VariantShatranj,"Button",BS_AUTORADIOBUTTON,154,\r
-                    84,70,10\r
-    CONTROL         "Seira&wan",OPT_VariantSChess,"Button",BS_AUTORADIOBUTTON,154,94,70,\r
-                    10\r
-    CONTROL         "&Grand",OPT_VariantGrand,"Button",BS_AUTORADIOBUTTON,154,104,70,\r
-                    10\r
-    CONTROL         "&xiangqi",OPT_VariantXiangqi,"Button",BS_AUTORADIOBUTTON,154,114,70,\r
-                    10\r
-    CONTROL         "&janggi",OPT_VariantJanggi,"Button",BS_AUTORADIOBUTTON,154,124,70,\r
-                    10\r
-    CONTROL         "",OPT_EngineVariant+0,"Button",BS_AUTORADIOBUTTON,9,134,70,10\r
-    CONTROL         "",OPT_EngineVariant+1,"Button",BS_AUTORADIOBUTTON,80,134,70,10\r
-    CONTROL         "",OPT_EngineVariant+2,"Button",BS_AUTORADIOBUTTON,154,134,70,10\r
-    CONTROL         "",OPT_EngineVariant+3,"Button",BS_AUTORADIOBUTTON,9,144,70,10\r
-    CONTROL         "",OPT_EngineVariant+4,"Button",BS_AUTORADIOBUTTON,80,144,70,10\r
-    CONTROL         "",OPT_EngineVariant+5,"Button",BS_AUTORADIOBUTTON,154,144,70,10\r
-    CONTROL         "",OPT_EngineVariant+6,"Button",BS_AUTORADIOBUTTON,9,154,70,10\r
-    CONTROL         "",OPT_EngineVariant+7,"Button",BS_AUTORADIOBUTTON,80,154,70,10\r
-    CONTROL         "",OPT_EngineVariant+8,"Button",BS_AUTORADIOBUTTON,154,154,70,10\r
-    CONTROL         "",OPT_EngineVariant+9,"Button",BS_AUTORADIOBUTTON,9,164,70,10\r
-    CONTROL         "",OPT_EngineVariant+10,"Button",BS_AUTORADIOBUTTON,80,164,70,10\r
-    CONTROL         "",OPT_EngineVariant+11,"Button",BS_AUTORADIOBUTTON,154,164,70,10\r
-    CONTROL         "",OPT_EngineVariant+12,"Button",BS_AUTORADIOBUTTON,9,174,70,10\r
-    CONTROL         "",OPT_EngineVariant+13,"Button",BS_AUTORADIOBUTTON,80,174,70,10\r
-    CONTROL         "",OPT_EngineVariant+14,"Button",BS_AUTORADIOBUTTON,154,174,70,10\r
-    GROUPBOX        "Variant",GPB_Variant,4,4,215,185\r
-    LTEXT           "Board size:",GPB_Board,10,203,40,8,WS_TABSTOP\r
-    LTEXT           "ranks",IDC_Height,77,203,38,8\r
-    EDITTEXT        IDC_Ranks,60,199,14,14,ES_AUTOHSCROLL\r
-    LTEXT           "files",IDC_Width,133,203,80,8\r
-    EDITTEXT        IDC_Files,116,199,14,14,ES_AUTOHSCROLL\r
-    LTEXT           "Holdings with room for:",IDC_Hand,10,221,90,8\r
-    EDITTEXT        IDC_Holdings,93,217,14,14,ES_AUTOHSCROLL\r
-    LTEXT           "pieces",IDC_Pieces,110,221,100,8\r
-    LTEXT           "('-1' means defaults for selected variant)",IDC_Def,10,237,210,8\r
-    DEFPUSHBUTTON   "OK",IDOK,114,252,50,14\r
-    PUSHBUTTON      "Cancel",IDCANCEL,170,252,50,14\r
+    LTEXT           "Variant",GPB_Variant,9,14,50,10\r
+    COMBOBOX        OPT_EngineVariant,60,14,150,129,CBS_DROPDOWN | \r
+                    CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP\r
+    LTEXT           "Board size:",GPB_Board,10,43,40,8,WS_TABSTOP\r
+    LTEXT           "ranks",IDC_Height,77,43,38,8\r
+    EDITTEXT        IDC_Ranks,60,39,14,14,ES_AUTOHSCROLL\r
+    LTEXT           "files",IDC_Width,133,183,80,8\r
+    EDITTEXT        IDC_Files,116,39,14,14,ES_AUTOHSCROLL\r
+    LTEXT           "Holdings with room for:",IDC_Hand,10,61,90,8\r
+    EDITTEXT        IDC_Holdings,93,57,14,14,ES_AUTOHSCROLL\r
+    LTEXT           "pieces",IDC_Pieces,110,61,100,8\r
+    LTEXT           "('-1' means defaults for selected variant)",IDC_Def,10,77,210,8\r
+    DEFPUSHBUTTON   "OK",IDOK,114,92,50,14\r
+    PUSHBUTTON      "Cancel",IDCANCEL,170,92,50,14\r
 END\r
 \r
 DLG_Fonts DIALOG DISCARDABLE  0, 0, 266, 274\r
index cf57d16..f712e4c 100644 (file)
@@ -825,7 +825,7 @@ BoardOptionsPopup(HWND hwnd)
   FreeProcInstance(lpProc);\r
 }\r
 \r
-int radioButton[] = {\r
+int radioButton[] = { // this is a remnant of the radiobuttons, and should be rewritten\r
     OPT_VariantNormal,\r
     -1, // Loadable\r
     OPT_VariantWildcastle,\r
@@ -876,45 +876,51 @@ int radioButton[] = {
     -2 // sentinel\r
 };\r
 \r
+VariantClass meaning[1000];\r
+\r
 VariantClass\r
 VariantWhichRadio(HWND hDlg)\r
 {\r
   int i=0, j;\r
   *engineVariant = NULLCHAR;\r
-  while((j = radioButton[i++]) != -2) {\r
-       if(j == -1) continue; // no menu button\r
-       if(IsDlgButtonChecked(hDlg, j) &&\r
-          (appData.noChessProgram || strstr(first.variants, VariantName(i-1)))) return (VariantClass) i-1;\r
-  }\r
-  for(i=0; i<15; i++) { // check for engine-defined variants\r
-    if(IsDlgButtonChecked(hDlg, OPT_EngineVariant+i) ) {\r
-       GetDlgItemText(hDlg, OPT_EngineVariant+i, engineVariant, MSG_SIZ); // remember name, so we can resolve it later\r
-       return VariantUnknown;\r
-    }\r
+  HWND combo = GetDlgItem(hDlg, OPT_EngineVariant);\r
+  j = SendMessage(combo, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);\r
+  if(j == CB_ERR) return gameInfo.variant; // nothing selected, keep old\r
+  i = meaning[j];\r
+  if(i == VariantUnknown) {\r
+    GetDlgItemText(hDlg, OPT_EngineVariant, engineVariant, MSG_SIZ);\r
   }\r
-  return gameInfo.variant; // If no button checked, keep old\r
+  return i;\r
 }\r
 \r
 void\r
 VariantShowRadio(HWND hDlg)\r
 {\r
   char c = *engineVariant, *v, *p;\r
-  int i=0, j;\r
-  CheckDlgButton(hDlg, radioButton[gameInfo.variant], TRUE);\r
-  *engineVariant = NULLCHAR; // [HGM] kludge to prevent VariantName will always return engineVariant\r
+  int i=0, j, nr = 0, current = 0;\r
+  HWND combo = GetDlgItem(hDlg, OPT_EngineVariant);\r
+  SendMessage(combo, CB_RESETCONTENT, 0, 0);\r
+  *engineVariant = NULLCHAR;  // [HGM] kludge to prevent VariantName will always return engineVariant\r
   while((j = radioButton[i++]) != -2) {\r
        if(j == -1) continue; // no menu button\r
        v = VariantName(i-1); p = strstr(first.variants, v);\r
-       EnableWindow(GetDlgItem(hDlg, j), appData.noChessProgram || p && (!*v || strlen(v) == strlen(p) || p[strlen(v)] == ','));\r
+       if(p && p != &first.variants && p[-1] != ',') p == NULL;\r
+       if(appData.noChessProgram || p && (!*v || strlen(v) == strlen(p) || p[strlen(v)] == ',')) {\r
+          SendMessage(combo, CB_ADDSTRING, 0, (LPARAM) v);\r
+           if(gameInfo.variant == i - 1) current = nr;\r
+          meaning[nr++] = i - 1;\r
+        }\r
   }\r
   *engineVariant = c;\r
-  for(i=0; i<15; i++) { // initialize engine-defined variants\r
+\r
+  for(i=0; ; i++) {\r
     char *v = EngineDefinedVariant(&first, i); // get name of #i\r
-    if(v) { // there is such a variant\r
-       EnableWindow(GetDlgItem(hDlg, OPT_EngineVariant+i), TRUE);     // and enable the button\r
-       SetDlgItemText(hDlg, OPT_EngineVariant+i, v);                  // put its name on button\r
-    } else EnableWindow(GetDlgItem(hDlg, OPT_EngineVariant+i), FALSE); // no such variant; disable button\r
+    if(!v || !*v) break;\r
+    SendMessage(combo, CB_ADDSTRING, 0, (LPARAM) v);\r
+    if(!strcmp(v, engineVariant)) current = nr;\r
+    meaning[nr++] = VariantUnknown;\r
   }\r
+  SendMessage(combo, CB_SETCURSEL, (WPARAM) current, (LPARAM) 0);\r
 }\r
 \r
 LRESULT CALLBACK\r