Allow engine to force popup of its settings dialog
authorH.G.Muller <hgm@hgm-xboard.(none)>
Sun, 31 Jan 2016 23:12:41 +0000 (00:12 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Mon, 1 Feb 2016 15:57:08 +0000 (16:57 +0100)
An engine can now force popping up of its settings dialog by sending
'feature done=3' to the GUI. It can clear its option list (e.g. for the
purpose of resending it because of altered settings) by sending
'feature done=0'. Such resending would cause the dialog to be updated
when it was already open, or close it and pop up a new one when the
engine specifies it has to be redesigned by ending the list with
'feature done=2'.

backend.c
backend.h
dialogs.c
dialogs.h
gtk/xoptions.c
xaw/xoptions.c

index c1234d7..6fca83d 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -16981,6 +16981,7 @@ ParseOption (Option *opt, ChessProgramState *cps)
        char *p, *q, buf[MSG_SIZ];
        int n, min = (-1)<<31, max = 1<<31, def;
 
+       opt->target = &opt->value;   // OK for spin/slider and checkbox
        if(p = strstr(opt->name, " -spin ")) {
            if((n = sscanf(p, " -spin %d %d %d", &def, &min, &max)) < 3 ) return FALSE;
            if(max < min) max = min; // enforce consistency
@@ -17003,14 +17004,17 @@ ParseOption (Option *opt, ChessProgramState *cps)
        } else if((p = strstr(opt->name, " -string "))) {
            opt->textValue = p+9;
            opt->type = TextBox;
+           opt->target = &opt->textValue;
        } else if((p = strstr(opt->name, " -file "))) {
            // for now -file is a synonym for -string, to already provide compatibility with future polyglots
-           opt->textValue = p+7;
+           opt->target = opt->textValue = p+7;
            opt->type = FileName; // FileName;
+           opt->target = &opt->textValue;
        } else if((p = strstr(opt->name, " -path "))) {
            // for now -file is a synonym for -string, to already provide compatibility with future polyglots
-           opt->textValue = p+7;
+           opt->target = opt->textValue = p+7;
            opt->type = PathName; // PathName;
+           opt->target = &opt->textValue;
        } else if(p = strstr(opt->name, " -check ")) {
            if(sscanf(p, " -check %d", &def) < 1) return FALSE;
            opt->value = (def != 0);
@@ -17074,9 +17078,9 @@ FeatureDone (ChessProgramState *cps, int val)
       (cb == TwoMachinesEventIfReady)) {
     CancelDelayedEvent();
     ScheduleDelayedEvent(cb, val ? 1 : 3600000);
-  }
+  } else if(!val && !cps->reload) ClearOptions(cps); // let 'spurious' done=0 clear engine's option list
   cps->initDone = val;
-  if(val) cps->reload = FALSE;
+  if(val) cps->reload = FALSE,  RefreshSettingsDialog(cps, val);
 }
 
 /* Parse feature command from engine */
index e2fc317..c148271 100644 (file)
--- a/backend.h
+++ b/backend.h
@@ -424,6 +424,7 @@ void LoadTheme P((void));
 void CreateBookEvent P((void));
 char *SupportedVariant P((char *list, VariantClass v, int w, int h, int s, int proto, char *engine));
 char *CollectPieceDescriptors P((void));
+void RefreshSettingsDialog P((ChessProgramState *cps, int val));
 
 
 /* A point in time */
index ea0ece7..3f445bb 100644 (file)
--- a/dialogs.c
+++ b/dialogs.c
@@ -93,11 +93,13 @@ int
 SetCurrentComboSelection (Option *opt)
 {
     int j;
+    if(currentCps) ; else
     if(!opt->textValue) opt->value = *(int*)opt->target; /* numeric */else {
        for(j=0; opt->choice[j]; j++) // look up actual value in list of possible values, to get selection nr
            if(*(char**)opt->target && !strcmp(*(char**)opt->target, ((char**)opt->textValue)[j])) break;
        opt->value = j + (opt->choice[j] == NULL);
     }
+    SetComboChoice(opt, opt->value);
     return opt->value;
 }
 
@@ -1460,6 +1462,22 @@ SecondSettingsProc ()
    SettingsPopUp(&second);
 }
 
+void
+RefreshSettingsDialog (ChessProgramState *cps, int val)
+{
+   if(val == 1) { // option values changed
+      if(shellUp[TransientDlg] && cps == currentCps) {
+         GenericUpdate(cps->option, -1); // normally update values when dialog is up
+      }
+      return; // and be done
+   }
+   if(val == 2) { // option list changed
+      if(!shellUp[TransientDlg] || cps != currentCps) return; // our dialog is not up, so nothing to do
+   }
+   PopDown(TransientDlg); // make sure any other dialog closes first
+   SettingsPopUp(cps);    // and popup new one
+}
+
 //----------------------------------------------- Load Engine --------------------------------------
 
 char *engineDir, *engineLine, *nickName, *params;
index 28259e7..ccc891f 100644 (file)
--- a/dialogs.h
+++ b/dialogs.h
@@ -154,6 +154,7 @@ void SetWidgetText  P((Option *opt, char *buf, int n));
 void GetWidgetState  P((Option *opt, int *state));
 void SetWidgetState  P((Option *opt, int state));
 void SetWidgetLabel P((Option *opt, char *buf));
+void SetComboChoice  P((Option *opt, int choice));
 void SetDialogTitle  P((DialogClass dlg, char *title));
 void LoadListBox P((Option *opt, char *emptyText, int n1, int n2));
 void HighlightListBoxItem P((Option *opt, int nr));
index 4a93b90..3df99a7 100644 (file)
@@ -244,6 +244,12 @@ SetWidgetLabel (Option *opt, char *buf)
 }
 
 void
+SetComboChoice (Option *opt, int n)
+{
+    gtk_combo_box_set_active(opt->handle, n);
+}
+
+void
 SetDialogTitle (DialogClass dlg, char *title)
 {
     gtk_window_set_title(GTK_WINDOW(shells[dlg]), title);
index 8f02a14..1809743 100644 (file)
@@ -189,6 +189,12 @@ SetWidgetLabel (Option *opt, char *buf)
 }
 
 void
+SetComboChoice (Option *opt, char *n)
+{
+    SetWidgetText(opt, opt->choice[n]);
+}
+
+void
 SetDialogTitle (DialogClass dlg, char *title)
 {
     Arg args[16];