Some experimenting with sizing
authorH.G. Muller <h.g.muller@hccnet.nl>
Sun, 21 Oct 2012 07:09:01 +0000 (09:09 +0200)
committerH.G. Muller <h.g.muller@hccnet.nl>
Tue, 6 Nov 2012 13:15:20 +0000 (14:15 +0100)
Does not work as intended yet.

dialogs.c
xboard.c
xoptions.c

index 60a932f..e95518f 100644 (file)
--- 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 , "" }
 };
 
index 0ac3a44..99bcad3 100644 (file)
--- 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
index e081bd7..a2f749f 100644 (file)
@@ -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).