Add displaying of icons
[xboard.git] / xoptions.c
index ae20ee1..e081bd7 100644 (file)
@@ -232,21 +232,13 @@ SetWidgetText (Option *opt, char *buf, int n)
 void
 GetWidgetState (Option *opt, int *state)
 {
-#ifdef TODO_GTK
-    Arg arg;
-    XtSetArg(arg, XtNstate, state);
-    XtGetValues(opt->handle, &arg, 1);
-#endif
+    *state = gtk_toggle_button_get_active(opt->handle);
 }
 
 void
 SetWidgetState (Option *opt, int state)
 {
-#ifdef TODO_GTK
-    Arg arg;
-    XtSetArg(arg, XtNstate, state);
-    XtSetValues(opt->handle, &arg, 1);
-#endif
+    gtk_toggle_button_set_active(opt->handle, state);
 }
 
 void
@@ -296,7 +288,7 @@ LoadListBox (Option *opt, char *emptyText, int n1, int n2)
 }
 
 void
-HighlightListBoxItem (Option *opt, int index)
+HighlightItem (Option *opt, int index, int scroll)
 {
     char *value, **data = (char **) (opt->target);
     GtkWidget *list = (GtkWidget *) (opt->handle);
@@ -305,15 +297,21 @@ HighlightListBoxItem (Option *opt, int index)
     GtkListStore *store = GTK_LIST_STORE(model);
     GtkTreePath *path = gtk_tree_path_new_from_indices(index, -1);
     GtkTreeIter iter;
-    gtk_tree_model_get_iter(GTK_TREE_MODEL (store), &iter, path);
+    gtk_tree_selection_select_path(selection, path);
+    if(scroll) gtk_tree_view_scroll_to_cell(list, path, NULL, 0, 0, 0);
     gtk_tree_path_free(path);
-    gtk_tree_selection_select_iter(selection, &iter);
 }
 
 void
-HighlightWithScroll (Option *opt, int sel, int max)
+HighlightListBoxItem (Option *opt, int index)
 {
-    HighlightListBoxItem (opt, index); // just highlight, as GTK scrolls by itself
+    HighlightItem (opt, index, FALSE);
+}
+
+void
+HighlightWithScroll (Option *opt, int index, int max)
+{
+    HighlightItem (opt, index, TRUE); // ignore max
 }
 
 int
@@ -340,6 +338,7 @@ FocusOnWidget (Option *opt, DialogClass dlg)
 #ifdef TODO_GTK
     XtSetKeyboardFocus(shells[dlg], opt->handle);
 #endif
+    gtk_widget_grab_focus(opt->handle);
 }
 
 void
@@ -448,9 +447,29 @@ char *translationTable[] = { // beware: order is essential!
    filterTranslations, gameListTranslations, memoTranslations
 };
 
+Option *typeIn; // kludge to distinguish type-in callback from input-box callback
+
+void
+CursorAtEnd (Option *opt)
+{
+    gtk_editable_set_position(opt->handle, -1);
+}
+
 static gboolean
-ICSKeyEvent(GtkWidget *widget, GdkEventKey *event)
+ICSKeyEvent(GtkWidget *widget, GdkEventKey *event, gpointer g)
 {
+    Option *opt = (Option *) g;
+    if(opt == typeIn) {
+       if(event->keyval == GDK_Return) {
+           char *val;
+           GetWidgetText(opt, &val);
+           TypeInDoneEvent(val);
+           PopDown(TransientDlg);
+           return TRUE;
+       }
+       return FALSE;
+    }
+
     switch(event->keyval) {
       case GDK_Return: IcsKey(0); return TRUE;
       case GDK_Up:     IcsKey(1); return TRUE;
@@ -512,6 +531,37 @@ ShiftKeys ()
 }
 
 static gboolean
+GameListEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata)
+{
+    int n = (int) gdata;
+
+    if(n == 4) {
+       if(((GdkEventKey *) event)->keyval != GDK_Return) return FALSE;
+       SetFilter();
+       return TRUE;
+    }
+
+    if(event->type == GDK_KEY_PRESS) {
+       int ctrl = (((GdkEventKey *) event)->state & GDK_CONTROL_MASK) != 0;
+       switch(((GdkEventKey *) event)->keyval) {
+         case GDK_Up: GameListClicks(-1 - 2*ctrl); return TRUE;
+         case GDK_Left: GameListClicks(-1); return TRUE;
+         case GDK_Down: GameListClicks(1 + 2*ctrl); return TRUE;
+         case GDK_Right: GameListClicks(1); return TRUE;
+         case GDK_Prior: GameListClicks(-4); return TRUE;
+         case GDK_Next: GameListClicks(4); return TRUE;
+         case GDK_Home: GameListClicks(-2); return TRUE;
+         case GDK_End: GameListClicks(2); return TRUE;
+         case GDK_Return: GameListClicks(0); return TRUE;
+         default: return FALSE;
+       }
+    }
+    if(event->type != GDK_2BUTTON_PRESS || ((GdkEventButton *) event)->button != 1) return FALSE;
+    GameListClicks(0);
+    return TRUE;
+}
+
+static gboolean
 MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata)
 {   // handle mouse clicks on text widgets that need it
     int w, h;
@@ -564,20 +614,25 @@ MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata)
 }
 
 void
-AddHandler (Option *opt, int nr)
+AddHandler (Option *opt, DialogClass dlg, int nr)
 {
     switch(nr) {
-      case 0: 
-      case 1: 
-      case 2: break;
-      case 3: g_signal_connect(opt->handle, "key-press-event", G_CALLBACK (ICSKeyEvent), NULL); break; // Input Box
-      case 4: 
-      case 5: 
-      case 6: break;
+      case 0: // history (now uses generic textview callback)
+      case 1: // comment (likewise)
+       break;
+      case 2: // move type-in
+       typeIn = opt;
+      case 3: // input box
+       g_signal_connect(opt->handle, "key-press-event", G_CALLBACK (ICSKeyEvent), (gpointer) opt);
+       break;
+      case 5: // game list
+       g_signal_connect(opt->handle, "button-press-event", G_CALLBACK (GameListEvent), (gpointer) 0 );
+      case 4: // game-list filter
+       g_signal_connect(opt->handle, "key-press-event", G_CALLBACK (GameListEvent), (gpointer) nr );
+       break;
+      case 6: // engine output (uses generic textview callback)
+       break;
     }
-#ifdef TODO_GTK
-    XtOverrideTranslations(opt->handle, XtParseTranslationTable(translationTable[nr]));
-#endif
 }
 
 //----------------------------Generic dialog --------------------------------------------
@@ -616,7 +671,9 @@ RaiseWindow (DialogClass dlg)
     xev.xclient.data.l[1] = CurrentTime;
 
     XSendEvent (xDisplay,
-          root, False,
+          root, False,static gboolean
+MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata)
+
           SubstructureRedirectMask | SubstructureNotifyMask,
           &xev);
 
@@ -923,6 +980,18 @@ void BrowseGTK(GtkWidget *widget, gpointer gdata)
     dialog = NULL;
 }
 
+gboolean
+ListCallback (GtkWidget *widget, GdkEventButton *event, gpointer gdata)
+{
+    int n = (intptr_t) gdata & 0xFFFF;
+    int dlg = (intptr_t) gdata >> 16;
+    Option *opt = dialogOptions[dlg] + n;
+
+    if(event->type != GDK_2BUTTON_PRESS || event->button != 1) return FALSE;
+    ((ListBoxCallback*) opt->textValue)(n, SelectedListBoxItem(opt));
+    return TRUE;
+}
+
 static char *oneLiner  =
    "<Key>Return: redraw-display() \n \
     <Key>Tab: TabProc() \n ";
@@ -995,16 +1064,26 @@ SetPositionAndSize (Arg *args, Widget leftNeigbor, Widget topNeigbor, int b, int
 #endif
 
 static int
+TableWidth (Option *opt)
+{   // Hideous work-around! If the table is 3 columns, but 2 & 3 are always occupied together, the fixing of the width of column 1 does not work
+    while(opt->type != EndMark && opt->type != Break)
+       if(opt->type == FileName || opt->type == PathName || opt++->type == BarBegin) return 3; // This table needs browse button
+    return 2; // no browse button;
+}
+
+static int
 SameRow (Option *opt)
 {
-    return (opt->min & SAME_ROW && (opt->type == Button || opt->type == SaveButton || opt->type == Label || opt->type == ListBox));
+    return (opt->min & SAME_ROW && (opt->type == Button || opt->type == SaveButton || opt->type == Label
+                                || opt->type == ListBox || opt->type == BoxBegin || opt->type == Icon));
 }
 
 static void
-Pack (GtkWidget *hbox, GtkWidget *table, GtkWidget *entry, int left, int right, int top)
+Pack (GtkWidget *hbox, GtkWidget *table, GtkWidget *entry, int left, int right, int top, GtkAttachOptions vExpand)
 {
     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);
+    else     gtk_table_attach(GTK_TABLE(table), entry, left, right, top, top+1,
+                               GTK_FILL | GTK_EXPAND, GTK_FILL | vExpand, 2, 1);
 }
 
 int
@@ -1016,7 +1095,8 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
     GtkWidget *box;
     GtkWidget *checkbutton;
     GtkWidget *entry;
-    GtkWidget *hbox = NULL;    
+    GtkWidget *oldHbox, *hbox = NULL;    
+    GtkWidget *pane = NULL;
     GtkWidget *button;
     GtkWidget *table;
     GtkWidget *spinner;    
@@ -1033,7 +1113,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
     GtkWidget *menuBar;    
     GtkWidget *menu;    
 
-    int i, j, arraysize, left, top, height=999, width=1, boxStart;    
+    int i, j, arraysize, left, top, height=999, width=1, boxStart, breakType = 0, r;    
     char def[MSG_SIZ], *msg, engineDlg = (currentCps != NULL && dlgNr != BrowserDlg);
 
     if(dlgNr < PromoDlg && shellUp[dlgNr]) return 0; // already up
@@ -1051,8 +1131,10 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
 
     if(engineDlg) { // Settings popup for engine: format through heuristic
         int n = currentCps->nrOptions;
-        if(n > 50) width = 4; else if(n>24) width = 2; else width = 1;
+//        if(n > 50) width = 4; else if(n>24) width = 2; else width = 1;
+       width = n / 20 + 1;
         height = n / width + 1;
+printf("n=%d, h=%d, w=%d\n",n,height,width);
 //     if(n && (currentOption[n-1].type == Button || currentOption[n-1].type == SaveButton)) currentOption[n].min = SAME_ROW; // OK on same line
         currentOption[n].type = EndMark; currentOption[n].target = NULL; // delimit list by callback-less end mark
     }    
@@ -1083,8 +1165,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
         arraysize++;   
     }
 
-    table = gtk_table_new(arraysize, 3, FALSE);
-    gtk_table_set_col_spacings(GTK_TABLE(table), 20);
+    table = gtk_table_new(arraysize, r=TableWidth(option), FALSE);
     left = 0;
     top = -1;    
 
@@ -1092,21 +1173,32 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
        if(option[i].type == -1) continue;
         top++;
         if (top >= height) {
+            gtk_table_resize(GTK_TABLE(table), height, r);
+           if(!pane) { // multi-column: put tables in intermediate hbox
+               if(breakType || engineDlg)
+                   pane =  gtk_hbox_new (FALSE, 0);
+               else
+                   pane =  gtk_vbox_new (FALSE, 0);
+               gtk_box_set_spacing(GTK_BOX(pane), 5 + 5*breakType);
+               gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), pane, TRUE, TRUE, 0);
+           }
+           gtk_box_pack_start (GTK_BOX (pane), table, TRUE, TRUE, 0);
+           table = gtk_table_new(arraysize - i, r=TableWidth(option + i), FALSE);
             top = 0;
-            left = left + 3;
-            gtk_table_resize(GTK_TABLE(table), height, left + 3);   
         }                
         if(!SameRow(&option[i])) {
            if(SameRow(&option[i+1])) {
+               GtkAttachOptions x = GTK_FILL;
                // 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(!currentCps && option[i].value > 80) x |= GTK_EXPAND; // only vertically extended widgets should size vertically
                 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);
+                    gtk_table_attach(GTK_TABLE(table), hbox, left, left+r, top, top+1, GTK_FILL | GTK_EXPAND, x, 2, 1);
                 else
-                    gtk_table_attach_defaults(GTK_TABLE(table), hbox, left+1, left+3, top, top+1);
+                    gtk_table_attach(GTK_TABLE(table), hbox, left+1, left+r, top, top+1, GTK_FILL | GTK_EXPAND, x, 2, 1);
            } else hbox = NULL; //and also make sure no hbox exists if only singl option on row
-        }
+        } else top--;
         switch(option[i].type) {
           case Fractional:           
            snprintf(def, MSG_SIZ,  "%.2f", *(float*)option[i].target);
@@ -1143,15 +1235,14 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                 gtk_widget_set_size_request(GTK_WIDGET(sw), w, -1);
  
                 textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));                
-                gtk_widget_set_size_request(textview, -1, option[i].min);
                 /* 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);
-                    Pack(hbox, table, sw, left+1, left+3, top);
+                    gtk_table_attach(GTK_TABLE(table), label, left, left+1, top, top+1, GTK_FILL, GTK_FILL, 2, 1);
+                    Pack(hbox, table, sw, left+1, left+r, top, 0);
                 }
                 else {
                     /* no label so let textview occupy all columns */
-                    Pack(hbox, table, sw, left, left+3, top);
+                    Pack(hbox, table, sw, left, left+r, top, GTK_EXPAND);
                 } 
                 if ( *(char**)option[i].target != NULL )
                     gtk_text_buffer_set_text (textbuffer, *(char**)option[i].target, -1);
@@ -1180,24 +1271,24 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
             gtk_entry_set_max_length (GTK_ENTRY (entry), w);
 
             // left, right, top, bottom
-            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), entry, 1, 2, i, i+1);            
+            if (strcmp(option[i].name, "") != 0)
+                gtk_table_attach(GTK_TABLE(table), label, left, left+1, top, top+1, GTK_FILL, GTK_FILL, 2, 1); // leading names do not expand
 
             if (option[i].type == Spin) {                
                 spinner_adj = (GtkAdjustment *) gtk_adjustment_new (option[i].value, option[i].min, option[i].max, 1.0, 0.0, 0.0);
                 spinner = gtk_spin_button_new (spinner_adj, 1.0, 0);
-                gtk_table_attach_defaults(GTK_TABLE(table), spinner, left+1, left+3, top, top+1);
+                gtk_table_attach(GTK_TABLE(table), spinner, left+1, left+r, top, top+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 2, 1);
                 option[i].handle = (void*)spinner;
             }
             else if (option[i].type == FileName || option[i].type == PathName) {
-                gtk_table_attach_defaults(GTK_TABLE(table), entry, left+1, left+2, top, top+1);
+                gtk_table_attach(GTK_TABLE(table), entry, left+1, left+2, top, top+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 2, 1);
                 button = gtk_button_new_with_label ("Browse");
-                gtk_table_attach_defaults(GTK_TABLE(table), button, left+2, left+3, top, top+1);
+                gtk_table_attach(GTK_TABLE(table), button, left+2, left+r, top, top+1, GTK_FILL, GTK_FILL, 2, 1); // Browse button does not expand
                 g_signal_connect (button, "clicked", G_CALLBACK (BrowseGTK), (gpointer)(intptr_t) i);
                 option[i].handle = (void*)entry;                 
             }
             else {
-                Pack(hbox, table, entry, left + (strcmp(option[i].name, "") != 0), left+3, top);
+                Pack(hbox, table, entry, left + (strcmp(option[i].name, "") != 0), left+r, top, 0);
                 option[i].handle = (void*)entry;
             }                                  
             break;
@@ -1205,9 +1296,14 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
             checkbutton = gtk_check_button_new_with_label(option[i].name);            
             if(!currentCps) option[i].value = *(Boolean*)option[i].target;
             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), option[i].value);
-            gtk_table_attach_defaults(GTK_TABLE(table), checkbutton, left, left+3, top, top+1);                            
+            gtk_table_attach(GTK_TABLE(table), checkbutton, left, left+r, top, top+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 2, 0);
             option[i].handle = (void *)checkbutton;            
             break; 
+         case Icon:            
+            option[i].handle = (void *) (label = gtk_image_new_from_pixbuf(NULL));
+            gtk_widget_set_size_request(label, option[i].max ? option[i].max : -1, -1);
+            Pack(hbox, table, label, left, left+2, top, 0);
+            break; 
          case Label:            
             option[i].handle = (void *) (label = gtk_label_new(option[i].name));
             /* Left Justify */
@@ -1217,7 +1313,8 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                 gtk_container_add(GTK_CONTAINER(frame), label);
                label = frame;
            }
-            Pack(hbox, table, label, left, left+3, top);
+            gtk_widget_set_size_request(label, option[i].max ? option[i].max : -1, -1);
+            Pack(hbox, table, label, left, left+2, top, 0);
            if(option[i].target) { // allow user to specify event handler for button presses
                gtk_widget_add_events(GTK_WIDGET(label), GDK_BUTTON_PRESS_MASK);
                g_signal_connect(label, "button-press-event", G_CALLBACK(MemoEvent), (gpointer) &option[i]);
@@ -1241,7 +1338,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                                         || strstr(first.variants, VariantName(option[i].value)));                 
             }
             
-            Pack(hbox, table, button, left, left+1, top);
+            Pack(hbox, table, button, left, left+1, top, 0);
             g_signal_connect (button, "clicked", G_CALLBACK (GenericCallback), (gpointer)(intptr_t) i + (dlgNr<<16));           
             option[i].handle = (void*)button;            
             break;  
@@ -1249,7 +1346,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
             label = gtk_label_new(option[i].name);
             /* Left Justify */
             gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-            gtk_table_attach_defaults(GTK_TABLE(table), label, left, left+1, top, top+1);
+            gtk_table_attach(GTK_TABLE(table), label, left, left+1, top, top+1, GTK_FILL, GTK_FILL, 2, 1);
 
             combobox = gtk_combo_box_new_text();            
 
@@ -1274,7 +1371,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); 
             
-            Pack(hbox, table, combobox, left+1, left+3, top);
+            Pack(hbox, table, combobox, left+1, left+r, top, 0);
             g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(ComboSelect), (gpointer) (intptr_t) (i + 256*dlgNr));
 
             option[i].handle = (void*)combobox;
@@ -1303,15 +1400,18 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                 gtk_container_add(GTK_CONTAINER(sw), list);
                 gtk_widget_set_size_request(GTK_WIDGET(sw), option[i].max ? option[i].max : -1, option[i].value ? option[i].value : -1);
  
+                if(option[i].textValue) // generic callback for double-clicking listbox item
+                    g_signal_connect(list, "button-press-event", G_CALLBACK(ListCallback), (gpointer) (dlgNr<<16 | i) );
+
                 /* never has label, so let listbox occupy all columns */
-                Pack(hbox, table, sw, left, left+3, top);
+                Pack(hbox, table, sw, left, left+r, top, GTK_EXPAND);
             }
            break;
          case Graph:
            option[i].handle = (void*) (graph = gtk_drawing_area_new());
             gtk_widget_set_size_request(graph, option[i].max, option[i].value);
 //         gtk_drawing_area_size(graph, option[i].max, option[i].value);
-            gtk_table_attach_defaults(GTK_TABLE(table), graph, left, left+3, top, top+1);
+            gtk_table_attach_defaults(GTK_TABLE(table), graph, left, left+r, top, top+1);
             g_signal_connect (graph, "expose-event", G_CALLBACK (GraphEventProc), (gpointer) &option[i]);
            gtk_widget_add_events(GTK_WIDGET(graph), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
             g_signal_connect (graph, "button-press-event", G_CALLBACK (GraphEventProc), (gpointer) &option[i]);
@@ -1366,18 +1466,30 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
          case BarBegin:
            menuBar = gtk_menu_bar_new ();
            gtk_widget_show (menuBar);
+           boxStart = i;
+           break;
          case BoxBegin:
+           option[i+1].min |= SAME_ROW; // kludge to suppress allocation of new hbox
+           oldHbox = hbox;
+           option[i].handle = (void*) (hbox = gtk_hbox_new(FALSE, 0)); // hbox to collect buttons
+           gtk_box_pack_start(GTK_BOX (oldHbox), hbox, FALSE, TRUE, 0); // *** Beware! Assumes button bar always on same row with other! ***
+//            gtk_table_attach(GTK_TABLE(table), hbox, left+2, left+3, top, top+1, GTK_FILL | GTK_SHRINK, GTK_FILL, 2, 1);
            boxStart = i;
            break;
          case BarEnd:
-            gtk_table_attach_defaults(GTK_TABLE(table), menuBar, left, left+1, top, top+1);
+            gtk_table_attach(GTK_TABLE(table), menuBar, left, left+r, top, top+1, GTK_FILL | GTK_EXPAND, GTK_FILL, 2, 1);
+           
+           if(option[i].target) ((ButtonCallback*)option[i].target)(boxStart); // callback that can make sizing decisions
+           break;
          case BoxEnd:
 //         XtManageChildren(&form, 1);
 //         SqueezeIntoBox(&option[boxStart], i-boxStart, option[boxStart].max);
+           hbox = oldHbox;
            if(option[i].target) ((ButtonCallback*)option[i].target)(boxStart); // callback that can make sizing decisions
            break;
          case Break:
-            if(option[i].min & SAME_ROW) top = height; // force next option to start in a new column
+            breakType = option[i].min & SAME_ROW;
+           top = height; // force next option to start in a new table
             break; 
        default:
            printf("GenericPopUp: unexpected case in switch. i=%d type=%d name=%s.\n", i, option[i].type, option[i].name);
@@ -1385,8 +1497,12 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
        }        
     }
 
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
-                        table, TRUE, TRUE, 0);    
+    if(pane)
+       gtk_box_pack_start (GTK_BOX (pane), table, TRUE, TRUE, 0);
+    else
+       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0);
+
+    option[i].handle = (void *) table; // remember last table in EndMark handle (for hiding Engine-Output pane).
 
     /* Show dialog */
     gtk_widget_show_all( dialog );