X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xoptions.c;h=e081bd7a1122a84ab6e5991a0c0a45cbaee971b0;hb=868622bc4b4ac3f5179909e9776ebcb309dd01c9;hp=14e6ff45838d628011ac0370c4ecbcd14043c9f5;hpb=a0228b1b0c78e941e2c4e3527fa004b186e157b2;p=xboard.git diff --git a/xoptions.c b/xoptions.c index 14e6ff4..e081bd7 100644 --- a/xoptions.c +++ b/xoptions.c @@ -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) +{ + HighlightItem (opt, index, FALSE); +} + +void +HighlightWithScroll (Option *opt, int index, int max) { - HighlightListBoxItem (opt, index); // just highlight, as GTK scrolls by itself + 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; @@ -459,6 +478,36 @@ ICSKeyEvent(GtkWidget *widget, GdkEventKey *event) } } +int shiftState, controlState; + +static gboolean +TypeInProc (GtkWidget *widget, GdkEventKey *event, gpointer gdata) +{ // This callback catches key presses on text-entries, and uses and as synonyms for dialog OK or Cancel + // *** kludge alert *** If a dialog does want some other action, like sending the line typed in the text-entry to an ICS, + // it should define an OK handler that does so, and returns FALSE to suppress the popdown. + int n = (intptr_t) gdata; + int dlg = n >> 16; + Option *opt; + n &= 0xFFFF; + opt = &dialogOptions[dlg][n]; + + if(opt == icsBox) return ICSKeyEvent(event->keyval); // Intercept ICS Input Box, which needs special treatment + + shiftState = event->state & GDK_SHIFT_MASK; + controlState = event->state & GDK_CONTROL_MASK; + switch(event->keyval) { + case GDK_Return: + if(GenericReadout(dialogOptions[dlg], -1)) PopDown(dlg); + break; + case GDK_Escape: + PopDown(dlg); + break; + default: + return FALSE; + } + return TRUE; +} + void HighlightText (Option *opt, int from, int to, Boolean highlight) { @@ -475,6 +524,43 @@ HighlightText (Option *opt, int from, int to, Boolean highlight) gtk_text_buffer_apply_tag_by_name(opt->handle, highlight ? "highlight" : "normal", &start, &end); } +int +ShiftKeys () +{ // bassic primitive for determining if modifier keys are pressed + return 3*(shiftState != 0) + 0xC*(controlState != 0); // rely on what last mouse button press left us +} + +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 @@ -489,6 +575,8 @@ MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata) gboolean res; gint index, x, y; + if(memo->type == Label) { ((ButtonCallback*) memo->target)(memo->value); return TRUE; } // only clock widgets use this + switch(event->type) { // figure out what's up case GDK_MOTION_NOTIFY: f = 0; @@ -502,6 +590,8 @@ MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata) case GDK_BUTTON_PRESS: w = bevent->x; h = bevent->y; button = bevent->button; + shiftState = bevent->state & GDK_SHIFT_MASK; + controlState = bevent->state & GDK_CONTROL_MASK; // GTK_TODO: is this really the most efficient way to get the character at the mouse cursor??? gtk_text_view_window_to_buffer_coords(widget, GTK_TEXT_WINDOW_WIDGET, w, h, &x, &y); gtk_text_view_get_iter_at_location(widget, &start, x, y); @@ -524,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 -------------------------------------------- @@ -576,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); @@ -760,6 +857,8 @@ GraphEventProc(GtkWidget *widget, GdkEvent *event, gpointer gdata) case GDK_BUTTON_PRESS: w = bevent->x; h = bevent->y; button = bevent->button; + shiftState = bevent->state & GDK_SHIFT_MASK; + controlState = bevent->state & GDK_CONTROL_MASK; } button *= f; @@ -881,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 = "Return: redraw-display() \n \ Tab: TabProc() \n "; @@ -953,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 @@ -974,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; @@ -991,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 @@ -1009,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 } @@ -1041,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; @@ -1050,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); @@ -1101,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); @@ -1138,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; @@ -1163,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 */ @@ -1175,7 +1313,12 @@ 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]); + } break; case SaveButton: case Button: @@ -1195,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; @@ -1203,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(); @@ -1228,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; @@ -1257,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]); @@ -1320,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); @@ -1339,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 );