Append recent engines to engine menu
authorH.G. Muller <h.g.muller@hccnet.nl>
Tue, 16 Oct 2012 07:34:02 +0000 (09:34 +0200)
committerH.G. Muller <h.g.muller@hccnet.nl>
Tue, 6 Nov 2012 13:13:54 +0000 (14:13 +0100)
This is now entirely moved to the back-end, by doing it in the table
from which the menus are later generated. The special callback for engine
items is abandoned, and the euProc for such items is left NULL to flag
that RecentEngineEvent should be invoked with the applicable engine number.
To calculate the latter a global variable firstEngineItem is dynamically
set to the length of the regular engine menu.

dialogs.c
menus.c
menus.h
xaw/xboard.c
xboard.c
xoptions.c

index ca2bd12..42d3f98 100644 (file)
--- a/dialogs.c
+++ b/dialogs.c
@@ -2073,7 +2073,7 @@ MenuCallback (int n)
 {
     MenuProc *proc = (MenuProc *) (((MenuItem*)(mainOptions[n].choice))[values[n]].proc);
 
-    (proc)();
+    if(!proc) RecentEngineEvent(values[n] - firstEngineItem); else (proc)();
 }
 
 static Option *
@@ -2143,6 +2143,7 @@ BoardPopUp (int squareSize, int lineGap, void *clockFontThingy)
     }
     if(!appData.showButtonBar) for(i=W_BUTTON; i<W_BOARD; i++) mainOptions[i].type = -1;
     for(i=0; i<8; i++) mainOptions[i+1].choice = (char**) menuBar[i].mi;
+    AppendEnginesToMenu(appData.recentEngineList);
     GenericPopUp(mainOptions, "XBoard", BoardWindow, BoardWindow, NONMODAL, 1);
     return mainOptions;
 }
diff --git a/menus.c b/menus.c
index 1d0e23d..a75bf5f 100644 (file)
--- a/menus.c
+++ b/menus.c
@@ -677,7 +677,7 @@ MenuItem actionMenu[] = {
     {NULL, NULL, NULL}
 };
 
-MenuItem engineMenu[] = {
+MenuItem engineMenu[100] = {
     {N_("Load New 1st Engine ..."), "LoadNew1stEngine", LoadEngine1Proc},
     {N_("Load New 2nd Engine ..."), "LoadNew2ndEngine", LoadEngine2Proc},
     {"----", NULL, NothingProc},
@@ -820,18 +820,22 @@ MenuNameToItem (char *menuName)
     return NULL; // item not found
 }
 
+int firstEngineItem;
+
 void
 AppendEnginesToMenu (char *list)
 {
     int i=0;
     char *p;
     if(appData.icsActive || appData.recentEngines <= 0) return;
+    for(firstEngineItem=0; engineMenu[firstEngineItem].string; firstEngineItem++);
     recentEngines = strdup(list);
     while (*list) {
        p = strchr(list, '\n'); if(p == NULL) break;
-       if(i == 0) AppendMenuItem("----", 0); // at least one valid item to add
+       if(i == 0) engineMenu[firstEngineItem++].string = "----"; // at least one valid item to add
        *p = 0;
-       AppendMenuItem(list, i);
+       if(firstEngineItem + i < 99)
+           engineMenu[firstEngineItem+i].string = strdup(list); // just set name; MenuProc stays NULL
        i++; *p = '\n'; list = p + 1;
     }
 }
diff --git a/menus.h b/menus.h
index c59c6df..7731256 100644 (file)
--- a/menus.h
+++ b/menus.h
@@ -55,15 +55,15 @@ typedef void MenuProc P((void));
 typedef int (*FileProc) P((FILE *f, int n, char *title));
 
 typedef struct {
-    String string;
-    String ref;
+    char *string;
+    char *ref;
     MenuProc *proc;
     void *handle;
 } MenuItem;
 
 typedef struct {
-    String name;
-    String ref;
+    char *name;
+    char *ref;
     MenuItem *mi;
 } Menu;
 
@@ -186,6 +186,7 @@ void CopySomething P((char *s));
 extern char  *gameCopyFilename, *gamePasteFilename;
 extern Boolean saveSettingsOnExit;
 extern char *settingsFileName;
+extern int firstEngineItem;
 
 
 
index 7fe789b..71416d4 100644 (file)
@@ -1265,7 +1265,6 @@ main (int argc, char **argv)
       XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
       XtGetValues(optList[W_PAUSE].handle, args, 2);
     }
-    AppendEnginesToMenu(appData.recentEngineList);
 
     xBoardWindow = XtWindow(boardWidget);
 
@@ -1623,18 +1622,6 @@ KeyBindingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
     if(item) ((MenuProc *) item->proc) ();
 }
 
-static void
-MenuEngineSelect (Widget w, caddr_t addr, caddr_t index)
-{
-    RecentEngineEvent((int) (intptr_t) addr);
-}
-
-void
-AppendMenuItem (char *msg, int n)
-{
-    CreateMenuItem((Widget) optList[W_ENGIN].textValue, msg, (XtCallbackProc) MenuEngineSelect, n);
-}
-
 void
 SetupDropMenu ()
 {
index f1c5425..845c168 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -1325,7 +1325,6 @@ main (int argc, char **argv)
       XtGetValues(optList[W_PAUSE].handle, args, 2);
     }
 #endif
-    AppendEnginesToMenu(appData.recentEngineList);
 
 #ifdef TODO_GTK
     xBoardWindow = XtWindow(boardWidget);
@@ -1684,22 +1683,6 @@ KeyBindingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 }
 #endif
 
-#ifdef TODO_GTK
-static void
-MenuEngineSelect (Widget w, caddr_t addr, caddr_t index)
-{
-    RecentEngineEvent((int) (intptr_t) addr);
-}
-#endif
-
-void
-AppendMenuItem (char *msg, int n)
-{
-#ifdef TODO_GTK
-    CreateMenuItem((Widget) optList[W_ENGIN].textValue, msg, (XtCallbackProc) MenuEngineSelect, n);
-#endif
-}
-
 void
 SetupDropMenu ()
 {
index d71d182..26e7d02 100644 (file)
@@ -1013,6 +1013,19 @@ SetPositionAndSize (Arg *args, Widget leftNeigbor, Widget topNeigbor, int b, int
 }
 #endif
 
+static int
+SameRow (Option *opt)
+{
+    return (opt->min & SAME_ROW && (opt->type == Button || opt->type == SaveButton || opt->type == Label || opt->type == ListBox));
+}
+
+static void
+Pack (GtkWidget *hbox, GtkWidget *table, GtkWidget *entry, int left, int right, int top)
+{
+    if(hbox) gtk_box_pack_start(GTK_BOX (hbox), entry, TRUE, TRUE, 0);
+    else     gtk_table_attach_defaults(GTK_TABLE(table), entry, left, right, top, top+1);
+}
+
 int
 GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent, int modal, int topLevel)
 {    
@@ -1022,7 +1035,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
     GtkWidget *box;
     GtkWidget *checkbutton;
     GtkWidget *entry;
-    GtkWidget *hbox;    
+    GtkWidget *hbox = NULL;    
     GtkWidget *button;
     GtkWidget *table;
     GtkWidget *spinner;    
@@ -1102,6 +1115,17 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
             left = left + 3;
             gtk_table_resize(GTK_TABLE(table), height, left + 3);   
         }                
+        if(!SameRow(&option[i])) {
+           if(SameRow(&option[i+1])) {
+               // make sure hbox is always available when we have more options on same row
+                hbox = gtk_hbox_new (option[i].type == Button && option[i].textValue, 0);
+                if (strcmp(option[i].name, "") == 0 || option[i].type == Label || option[i].type == Button)
+                    // for Label and Button name is contained inside option
+                    gtk_table_attach_defaults(GTK_TABLE(table), hbox, left, left+3, top, top+1);
+                else
+                    gtk_table_attach_defaults(GTK_TABLE(table), hbox, left+1, left+3, top, top+1);
+           } else hbox = NULL; //and also make sure no hbox exists if only singl option on row
+        }
         switch(option[i].type) {
           case Fractional:           
            snprintf(def, MSG_SIZ,  "%.2f", *(float*)option[i].target);
@@ -1142,11 +1166,11 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                 /* check if label is empty */ 
                 if (strcmp(option[i].name,"") != 0) {
                     gtk_table_attach_defaults(GTK_TABLE(table), label, left, left+1, top, top+1);
-                    gtk_table_attach_defaults(GTK_TABLE(table), sw, left+1, left+3, top, top+1);
+                    Pack(hbox, table, sw, left+1, left+3, top);
                 }
                 else {
                     /* no label so let textview occupy all columns */
-                    gtk_table_attach_defaults(GTK_TABLE(table), sw, left, left+3, top, top+1);
+                    Pack(hbox, table, sw, left, left+3, top);
                 } 
                 if ( *(char**)option[i].target != NULL )
                     gtk_text_buffer_set_text (textbuffer, *(char**)option[i].target, -1);
@@ -1186,13 +1210,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                 option[i].handle = (void*)entry;                 
             }
             else {
-                hbox = gtk_hbox_new (FALSE, 0);
-                if (strcmp(option[i].name, "") == 0)
-                    gtk_table_attach_defaults(GTK_TABLE(table), hbox, left, left+3, top, top+1);
-                else
-                    gtk_table_attach_defaults(GTK_TABLE(table), hbox, left+1, left+3, top, top+1);
-                gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
-                //gtk_table_attach_defaults(GTK_TABLE(table), entry, left+1, left+3, top, top+1); 
+                Pack(hbox, table, entry, left + (strcmp(option[i].name, "") != 0), left+3, top);
                 option[i].handle = (void*)entry;
             }                                  
             break;
@@ -1212,7 +1230,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                 gtk_container_add(GTK_CONTAINER(frame), label);
                label = frame;
            }
-            gtk_table_attach_defaults(GTK_TABLE(table), label, left, left+3, top, top+1);                       
+            Pack(hbox, table, label, left, left+3, top);                       
            break;
           case SaveButton:
           case Button:
@@ -1232,18 +1250,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                                         || strstr(first.variants, VariantName(option[i].value)));                 
             }
             
-            if (!(option[i].min & 1)) {
-               if(option[i].textValue) // for new variant dialog give buttons equal space so they line up nicely
-                   hbox = gtk_hbox_new (TRUE, 0);
-               else
-                   hbox = gtk_hbox_new (FALSE, 0);
-               // if only 1 button then put it in 1st column of table only
-               if ( (arraysize >= (i+1)) && option[i+1].type != Button )
-                   gtk_table_attach_defaults(GTK_TABLE(table), hbox, left, left+1, top, top+1);
-               else
-                   gtk_table_attach_defaults(GTK_TABLE(table), hbox, left, left+3, top, top+1);
-            }            
-            gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);           
+            Pack(hbox, table, button, left, left+1, top);
             g_signal_connect (button, "clicked", G_CALLBACK (GenericCallback), (gpointer)(intptr_t) i + (dlgNr<<16));           
             option[i].handle = (void*)button;            
             break;  
@@ -1276,12 +1283,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
             //option[i].value = j + (option[i].choice[j] == NULL);            
             gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), option[i].value); 
             
-
-            hbox = gtk_hbox_new (FALSE, 0);
-            gtk_table_attach_defaults(GTK_TABLE(table), hbox, left+1, left+3, top, top+1);
-            gtk_box_pack_start (GTK_BOX (hbox), combobox, TRUE, TRUE, 0);
-            //gtk_table_attach_defaults(GTK_TABLE(table), combobox, 1, 2, i, i+1);
-
+            Pack(hbox, table, combobox, left+1, left+3, top);
             g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(ComboSelect), (gpointer) (intptr_t) (i + 256*dlgNr));
 
             option[i].handle = (void*)combobox;
@@ -1311,7 +1313,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                 gtk_widget_set_size_request(GTK_WIDGET(sw), w, 300);
  
                 /* never has label, so let listbox occupy all columns */
-                gtk_table_attach_defaults(GTK_TABLE(table), sw, left, left+3, top, top+1);
+                Pack(hbox, table, sw, left, left+3, top);
             }
            break;
          case Graph:
@@ -1410,9 +1412,6 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
     g_signal_connect (dialog, "delete-event",
                       G_CALLBACK (GenericPopDown),
                       (gpointer)(intptr_t) dlgNr);
-    g_signal_connect (dialog, "destroy-event",
-                      G_CALLBACK (GenericPopDown),
-                      (gpointer)(intptr_t) dlgNr);
     shellUp[dlgNr]++;
 
 #ifdef TODO_GTK