From 2c8b216df0104d058c76fae14159b35fdecfe00b Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Sun, 21 Oct 2012 09:09:01 +0200 Subject: [PATCH] Some experimenting with sizing Does not work as intended yet. --- dialogs.c | 2 + xboard.c | 70 ++++++++++++++++++++++++++++++++++++++++++----------------- xoptions.c | 35 ++++++++++++++++++++--------- 3 files changed, 76 insertions(+), 31 deletions(-) diff --git a/dialogs.c b/dialogs.c index 60a932f..e95518f 100644 --- a/dialogs.c +++ b/dialogs.c @@ -2084,6 +2084,8 @@ Option mainOptions[] = { // description of main window in terms of generic dialo { 2, COMBO_CALLBACK, 0, NULL, (void*) &PMSelect, NULL, pieceMenuStrings[0], PopUp, "menuW" }, { 2, COMBO_CALLBACK, 0, NULL, (void*) &PMSelect, NULL, pieceMenuStrings[1], PopUp, "menuB" }, { -1, COMBO_CALLBACK, 0, NULL, (void*) &PMSelect, NULL, dropMenuStrings, PopUp, "menuD" }, +{ 0, 0, 0, NULL, (void*) &appData.saveGameFile, ".pgn .game", NULL, FileName, N_("Save Tourney Games on:") }, +//{ 0, 0, 0, NULL, NULL, "", NULL, EndMark , "" }, { 0, NO_OK, 0, NULL, NULL, "", NULL, EndMark , "" } }; diff --git a/xboard.c b/xboard.c index 0ac3a44..99bcad3 100644 --- a/xboard.c +++ b/xboard.c @@ -222,6 +222,7 @@ void DisplayMove P((int moveNumber)); void ICSInitScript P((void)); void update_ics_width P(()); int CopyMemoProc P(()); +static gboolean EventProc P((GtkWidget *widget, GdkEvent *event, gpointer g)); #ifdef TODO_GTK /* @@ -762,6 +763,19 @@ ParseCommPortSettings (char *s) int frameX, frameY; +void +GetActualPlacement (GtkWidget *shell, WindowPlacement *wp) +{ + GtkAllocation a; + if(!shell) return; + gtk_widget_get_allocation(shell, &a); + wp->x = a.x; + wp->y = a.y; + wp->width = a.width; + wp->height = a.height; +printf("placement\n"); + frameX = a.x; frameY = a.y; // remember to decide if windows touch +} #ifdef TODO_GTK void GetActualPlacement (Widget wg, WindowPlacement *wp) @@ -787,7 +801,6 @@ void GetWindowCoords () { // wrapper to shield use of window handles from back-end (make addressible by number?) // In XBoard this will have to wait until awareness of window parameters is implemented -#ifdef TODO_GTK GetActualPlacement(shellWidget, &wpMain); if(shellUp[EngOutDlg]) GetActualPlacement(shells[EngOutDlg], &wpEngineOutput); if(shellUp[HistoryDlg]) GetActualPlacement(shells[HistoryDlg], &wpMoveHistory); @@ -795,7 +808,6 @@ GetWindowCoords () if(shellUp[GameListDlg]) GetActualPlacement(shells[GameListDlg], &wpGameList); if(shellUp[CommentDlg]) GetActualPlacement(shells[CommentDlg], &wpComment); if(shellUp[TagsDlg]) GetActualPlacement(shells[TagsDlg], &wpTags); -#endif } void @@ -815,7 +827,7 @@ MainWindowUp () #ifdef TODO_GTK return xBoardWindow != 0; #else - return 0; + return DialogExists(BoardWindow); #endif } @@ -850,6 +862,9 @@ ConvertToLine (int argc, char **argv) void ResizeBoardWindow (int w, int h, int inhibit) { + w += marginW + 1; // [HGM] not sure why the +1 is (sometimes) needed... + h += marginH; +// gtk_window_resize(GTK_WINDOW(shellWidget), w, h); #ifdef TODO_GTK w += marginW + 1; // [HGM] not sure why the +1 is (sometimes) needed... h += marginH; @@ -1276,6 +1291,7 @@ main (int argc, char **argv) 0); #endif InitDrawingHandle(optList + W_BOARD); + shellWidget = shells[BoardWindow]; currBoard = &optList[W_BOARD]; boardWidget = optList[W_BOARD].handle; menuBarWidget = optList[W_MENU].handle; @@ -1331,6 +1347,12 @@ main (int argc, char **argv) shellArgs[5].value = shellArgs[3].value = h; // XtSetValues(shellWidget, &shellArgs[2], 4); #endif + { + GtkAllocation a; + gtk_widget_get_allocation(shells[BoardWindow], &a); + w = a.width; h = a.height; +printf("start size (%d,%d), %dx%d\n", a.x, a.y, w, h); + } marginW = w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board marginH = h - boardHeight; @@ -1361,6 +1383,7 @@ main (int argc, char **argv) (XtEventHandler) EventProc, NULL); #endif g_signal_connect(shells[BoardWindow], "key-press-event", G_CALLBACK(KeyPressProc), NULL); + g_signal_connect(shells[BoardWindow], "configure-event", G_CALLBACK(EventProc), NULL); /* [AS] Restore layout */ if( wpMoveHistory.visible ) { @@ -1715,11 +1738,9 @@ Fraction (int x, int start, int stop) static WindowPlacement wpNew; -#ifdef TODO_GTK void -CoDrag (Widget sh, WindowPlacement *wp) +CoDrag (GtkWidget *sh, WindowPlacement *wp) { - Arg args[16]; int j=0, touch=0, fudge = 2; GetActualPlacement(sh, wp); if(abs(wpMain.x + wpMain.width + 2*frameX - wp->x) < fudge) touch = 1; else // right touch @@ -1733,14 +1754,18 @@ CoDrag (Widget sh, WindowPlacement *wp) double fracBot = Fraction(wp->y + wp->height + frameX + frameY + 1, wpMain.y, wpMain.y + wpMain.height + frameX + frameY); wp->y += fracTop * heightInc; heightInc = (int) (fracBot * heightInc) - (int) (fracTop * heightInc); +#ifdef TODO_GTK if(heightInc) XtSetArg(args[j], XtNheight, wp->height + heightInc), j++; +#endif } else if(touch > 2 && wpNew.width != wpMain.width) { // top or bottom and width changed int widthInc = wpNew.width - wpMain.width; double fracLeft = Fraction(wp->x, wpMain.x, wpMain.x + wpMain.width + 2*frameX); double fracRght = Fraction(wp->x + wp->width + 2*frameX + 1, wpMain.x, wpMain.x + wpMain.width + 2*frameX); wp->y += fracLeft * widthInc; widthInc = (int) (fracRght * widthInc) - (int) (fracLeft * widthInc); +#ifdef TODO_GTK if(widthInc) XtSetArg(args[j], XtNwidth, wp->width + widthInc), j++; +#endif } wp->x += wpNew.x - wpMain.x; wp->y += wpNew.y - wpMain.y; @@ -1775,7 +1800,7 @@ ReSize (WindowPlacement *wp) #ifdef TODO_GTK static XtIntervalId delayedDragID = 0; #else -static int delayedDragID = 0; +static guint delayedDragTag = 0; #endif void @@ -1785,7 +1810,8 @@ DragProc () if(busy) return; busy = 1; - GetActualPlacement(shellWidget, &wpNew); +// GetActualPlacement(shellWidget, &wpNew); +printf("drag proc (%d,%d) %dx%d\n", wpNew.x, wpNew.y, wpNew.width, wpNew.height); if(wpNew.x == wpMain.x && wpNew.y == wpMain.y && // not moved wpNew.width == wpMain.width && wpNew.height == wpMain.height) { // not sized busy = 0; return; // false alarm @@ -1797,29 +1823,33 @@ DragProc () if(shellUp[GameListDlg]) CoDrag(shells[GameListDlg], &wpGameList); wpMain = wpNew; DrawPosition(True, NULL); - delayedDragID = 0; // now drag executed, make sure next DelayedDrag will not cancel timer event (which could now be used by other) + if(delayedDragTag) g_source_remove(delayedDragTag); + delayedDragTag = 0; // now drag executed, make sure next DelayedDrag will not cancel timer event (which could now be used by other) busy = 0; } -#endif void DelayedDrag () { -#ifdef TODO_GTK - if(delayedDragID) XtRemoveTimeOut(delayedDragID); // cancel pending - delayedDragID = - XtAppAddTimeOut(appContext, 200, (XtTimerCallbackProc) DragProc, (XtPointer) 0); // and schedule new one 50 msec later -#endif +printf("old timr = %d\n", delayedDragTag); + if(delayedDragTag) g_source_remove(delayedDragTag); + delayedDragTag = g_timeout_add( 200, (GSourceFunc) DragProc, NULL); +printf("new timr = %d\n", delayedDragTag); } -#ifdef TODO_GTK -void -EventProc (Widget widget, caddr_t unused, XEvent *event) +static gboolean +EventProc (GtkWidget *widget, GdkEvent *event, gpointer g) { - if(XtIsRealized(widget) && event->type == ConfigureNotify || appData.useStickyWindows) +printf("event proc (%d,%d) %dx%d\n", event->configure.x, event->configure.y, event->configure.width, event->configure.height); + // immediately + wpNew.x = event->configure.x; + wpNew.y = event->configure.y; + wpNew.width = event->configure.width; + wpNew.height = event->configure.height; + if(appData.useStickyWindows) DelayedDrag(); // as long as events keep coming in faster than 50 msec, they destroy each other + return FALSE; } -#endif /* * event handler for redrawing the board diff --git a/xoptions.c b/xoptions.c index e081bd7..a2f749f 100644 --- a/xoptions.c +++ b/xoptions.c @@ -804,6 +804,7 @@ GraphEventProc(GtkWidget *widget, GdkEvent *event, gpointer gdata) GdkEventExpose *eevent = (GdkEventExpose *) event; GdkEventButton *bevent = (GdkEventButton *) event; GdkEventMotion *mevent = (GdkEventMotion *) event; + GtkAllocation a; cairo_t *cr; // if (!XtIsRealized(widget)) return; @@ -811,33 +812,38 @@ GraphEventProc(GtkWidget *widget, GdkEvent *event, gpointer gdata) switch(event->type) { case GDK_EXPOSE: // make handling of expose events generic, just copying from memory buffer (->choice) to display (->textValue) /* Get window size */ + gtk_widget_get_allocation(widget, &a); + w = a.width; h = a.height; +//printf("expose %dx%d @ (%d,%d)\n", w, h, a.x, a.y); #ifdef TODO_GTK j = 0; XtSetArg(args[j], XtNwidth, &w); j++; XtSetArg(args[j], XtNheight, &h); j++; XtGetValues(widget, args, j); - +#endif if(w < graph->max || w > graph->max + 1 || h != graph->value) { // use width fudge of 1 pixel - if(((XExposeEvent*)event)->count >= 0) { // suppress sizing on expose for ordered redraw in response to sizing. + if(eevent->count >= 0) { // suppress sizing on expose for ordered redraw in response to sizing. sizing = 1; graph->max = w; graph->value = h; // note: old values are kept if we we don't exceed width fudge } } else w = graph->max; - - if(sizing && ((XExposeEvent*)event)->count > 0) { graph->max = 0; return; } // don't bother if further exposure is pending during resize + if(sizing && eevent->count > 0) { graph->max = 0; return; } // don't bother if further exposure is pending during resize +#ifdef TODO_GTK if(!graph->textValue || sizing) { // create surfaces of new size for display widget if(graph->textValue) cairo_surface_destroy((cairo_surface_t *)graph->textValue); graph->textValue = (char*) cairo_xlib_surface_create(xDisplay, XtWindow(widget), DefaultVisual(xDisplay, 0), w, h); } +#endif if(sizing) { // the memory buffer was already created in GenericPopup(), // to give drawing routines opportunity to use it before first expose event // (which are only processed when main gets to the event loop, so after all init!) // so only change when size is no longer good +#ifdef TODO_GTK if(graph->choice) cairo_surface_destroy((cairo_surface_t *) graph->choice); graph->choice = (char**) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); +#endif break; } -#endif w = eevent->area.width; if(eevent->area.x + w > graph->max) w--; // cut off fudge pixel cr = gdk_cairo_create(((GtkWidget *) (graph->handle))->window); @@ -1158,7 +1164,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width); shells[dlgNr] = dialog; box = gtk_dialog_get_content_area( GTK_DIALOG( dialog ) ); - gtk_box_set_spacing(GTK_BOX(box), 5); +// gtk_box_set_spacing(GTK_BOX(box), 5); arraysize = 0; for (i=0;option[i].type != EndMark;i++) { @@ -1172,6 +1178,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width); for (i=0;option[i].type != EndMark;i++) { if(option[i].type == -1) continue; top++; +printf("option =%2d, top =%2d\n", i, top); if (top >= height) { gtk_table_resize(GTK_TABLE(table), height, r); if(!pane) { // multi-column: put tables in intermediate hbox @@ -1180,7 +1187,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width); 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 (/*GTK_DIALOG (dialog)->vbox*/box), 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); @@ -1410,8 +1417,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width); 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+r, top, top+1); + Pack(hbox, GTK_TABLE(table), graph, left, left+r, top, GTK_EXPAND); 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]); @@ -1452,6 +1458,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width); break; #endif case DropDown: + top--; msg = _(option[i].name); // write name on the menu button // XtSetArg(args[j], XtNmenuName, XtNewString(option[i].name)); j++; // XtSetArg(args[j], XtNlabel, msg); j++; @@ -1477,6 +1484,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width); boxStart = i; break; case BarEnd: + top--; 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 @@ -1484,13 +1492,17 @@ printf("n=%d, h=%d, w=%d\n",n,height,width); case BoxEnd: // XtManageChildren(&form, 1); // SqueezeIntoBox(&option[boxStart], i-boxStart, option[boxStart].max); - hbox = oldHbox; + hbox = oldHbox; top--; if(option[i].target) ((ButtonCallback*)option[i].target)(boxStart); // callback that can make sizing decisions break; case Break: breakType = option[i].min & SAME_ROW; top = height; // force next option to start in a new table break; + + case PopUp: + top--; + break; default: printf("GenericPopUp: unexpected case in switch. i=%d type=%d name=%s.\n", i, option[i].type, option[i].name); break; @@ -1500,7 +1512,8 @@ printf("n=%d, h=%d, w=%d\n",n,height,width); 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); + gtk_table_resize(GTK_TABLE(table), top+1, r), + gtk_box_pack_start (GTK_BOX (/*GTK_DIALOG (dialog)->vbox*/box), table, TRUE, TRUE, 0); option[i].handle = (void *) table; // remember last table in EndMark handle (for hiding Engine-Output pane). -- 1.7.0.4