X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xoptions.c;h=558da5862cc10b10fbd7afdf5549cb5a6194f082;hb=5cd55bddca592918f38deff675d05b650a71412e;hp=6c3d8aa56858b120852db23dc269ee0b4da20ad7;hpb=28101503eb34658db6951f45f8b83bf769f2b330;p=xboard.git diff --git a/xoptions.c b/xoptions.c index 6c3d8aa..558da58 100644 --- a/xoptions.c +++ b/xoptions.c @@ -1,7 +1,7 @@ /* * xoptions.c -- Move list window, part of X front end for XBoard * - * Copyright 2000,2009 Free Software Foundation, Inc. + * Copyright 2000, 2009, 2010 Free Software Foundation, Inc. * ------------------------------------------------------------------------ * * GNU XBoard is free software: you can redistribute it and/or modify @@ -45,6 +45,7 @@ extern char *getenv(); #if HAVE_UNISTD_H # include #endif +#include #include #include @@ -88,6 +89,7 @@ extern char *layoutName; extern Window xBoardWindow; extern Arg layoutArgs[2], formArgs[2]; Pixel timerForegroundPixel, timerBackgroundPixel; +extern int searchTime; // [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines @@ -245,6 +247,7 @@ int tcIncrement, tcMoves; void TimeControlPopDown() { if (!TimeControlUp) return; + previous = NULL; XtPopdown(TimeControlShell); XtDestroyWidget(TimeControlShell); TimeControlUp = False; @@ -265,54 +268,77 @@ void TimeControlCallback(w, client_data, call_data) XtGetValues(w, args, 1); if (strcmp(name, _("classical")) == 0) { - if(!tcInc) return; + if(tcInc == 0) return; j=0; XtSetArg(args[j], XtNlabel, _("minutes for each")); j++; XtSetValues(tcMess1, args, j); j=0; XtSetArg(args[j], XtNlabel, _("moves")); j++; XtSetValues(tcMess2, args, j); - j=0; - XtSetArg(args[j], XtNstring, &name); j++; - XtGetValues(tcData, args, j); - tcIncrement = 0; sscanf(name, "%d", &tcIncrement); + if(tcInc == 1) { + j=0; + XtSetArg(args[j], XtNstring, &name); j++; + XtGetValues(tcData, args, j); + tcIncrement = 0; sscanf(name, "%d", &tcIncrement); + } sprintf(buf, "%d", tcMoves); j=0; XtSetArg(args[j], XtNstring, buf); j++; XtSetValues(tcData, args, j); - tcInc = False; + tcInc = 0; return; } if (strcmp(name, _("incremental")) == 0) { - if(tcInc) return; + if(tcInc == 1) return; j=0; XtSetArg(args[j], XtNlabel, _("minutes, plus")); j++; XtSetValues(tcMess1, args, j); j=0; XtSetArg(args[j], XtNlabel, _("sec/move")); j++; XtSetValues(tcMess2, args, j); - j=0; - XtSetArg(args[j], XtNstring, &name); j++; - XtGetValues(tcData, args, j); - tcMoves = appData.movesPerSession; sscanf(name, "%d", &tcMoves); + if(tcInc == 0) { + j=0; + XtSetArg(args[j], XtNstring, &name); j++; + XtGetValues(tcData, args, j); + tcMoves = appData.movesPerSession; sscanf(name, "%d", &tcMoves); + } sprintf(buf, "%d", tcIncrement); j=0; XtSetArg(args[j], XtNstring, buf); j++; XtSetValues(tcData, args, j); - tcInc = True; + tcInc = 1; + return; + } + if (strcmp(name, _("fixed time")) == 0) { + if(tcInc == 2) return; + j=0; + XtSetArg(args[j], XtNlabel, _("sec/move (max)")); j++; + XtSetValues(tcMess1, args, j); + j=0; + XtSetArg(args[j], XtNlabel, _("")); j++; + XtSetValues(tcMess2, args, j); + j=0; + XtSetArg(args[j], XtNstring, ""); j++; + XtSetValues(tcData, args, j); + tcInc = 2; return; } if (strcmp(name, _(" OK ")) == 0) { int inc, mps, tc, ok; XtSetArg(args[0], XtNstring, &txt); XtGetValues(tcData, args, 1); - if(tcInc) { + switch(tcInc) { + case 1: ok = sscanf(txt, "%d", &inc); mps = 0; if(!ok && txt[0] == 0) { inc = 0; ok = 1; } // accept empty string as zero ok &= (inc >= 0); - } else { + break; + case 0: ok = sscanf(txt, "%d", &mps); inc = -1; ok &= (mps > 0); + break; + case 2: + ok = 1; inc = -1; mps = 40; } if(ok != 1) { XtSetArg(args[0], XtNstring, ""); // erase any offending input @@ -321,15 +347,26 @@ void TimeControlCallback(w, client_data, call_data) } XtSetArg(args[0], XtNstring, &txt); XtGetValues(tcTime, args, 1); - if(!ParseTimeControl(txt, inc, mps)) { - XtSetArg(args[0], XtNstring, ""); // erase any offending input - XtSetValues(tcTime, args, 1); - DisplayError(_("Bad Time-Control String"), 0); - return; + if(tcInc == 2) { + if(sscanf(txt, "%d", &inc) != 1) { + XtSetArg(args[0], XtNstring, ""); // erase any offending input + XtSetValues(tcTime, args, 1); + DisplayError(_("Bad Time-Control String"), 0); + return; + } + searchTime = inc; + } else { + if(!ParseTimeControl(txt, inc, mps)) { + XtSetArg(args[0], XtNstring, ""); // erase any offending input + XtSetValues(tcTime, args, 1); + DisplayError(_("Bad Time-Control String"), 0); + return; + } + searchTime = 0; + appData.movesPerSession = mps; + appData.timeIncrement = inc; + appData.timeControl = strdup(txt); } - appData.movesPerSession = mps; - appData.timeIncrement = inc; - appData.timeControl = strdup(txt); XtSetArg(args[0], XtNstring, &txt); XtGetValues(tcOdds1, args, 1); appData.firstTimeOdds = first.timeOdds @@ -354,7 +391,7 @@ void TimeControlPopUp() unsigned int mask; char def[80]; - tcInc = (appData.timeIncrement >= 0); + tcInc = searchTime > 0 ? 2 : (appData.timeIncrement >= 0); tcMoves = appData.movesPerSession; tcIncrement = appData.timeIncrement; if(!tcInc) tcIncrement = 0; sprintf(def, "%d", tcInc ? tcIncrement : tcMoves); @@ -396,7 +433,7 @@ void TimeControlPopUp() XtAddEventHandler(tcTime, ButtonPressMask, False, SetFocus, (XtPointer) popup); j= 0; - XtSetArg(args[j], XtNlabel, tcInc ? _(" minutes, plus ") : _("minutes for each")); j++; + XtSetArg(args[j], XtNlabel, tcInc ? tcInc == 2 ? _("sec/move (max) ") : _(" minutes, plus ") : _("minutes for each")); j++; XtSetArg(args[j], XtNborderWidth, 0); j++; XtSetArg(args[j], XtNfromHoriz, tcTime); j++; XtSetArg(args[j], XtNtop, XtChainTop); j++; @@ -425,7 +462,7 @@ void TimeControlPopUp() XtAddEventHandler(tcData, ButtonPressMask, False, SetFocus, (XtPointer) popup); j= 0; - XtSetArg(args[j], XtNlabel, tcInc ? _("sec/move") : _("moves ")); j++; + XtSetArg(args[j], XtNlabel, tcInc ? tcInc == 2 ? _(" ") : _("sec/move") : _("moves ")); j++; XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; XtSetArg(args[j], XtNborderWidth, 0); j++; XtSetArg(args[j], XtNfromHoriz, tcData); j++; @@ -493,18 +530,34 @@ void TimeControlPopUp() XtSetArg(args[j], XtNtop, XtChainBottom); j++; XtSetArg(args[j], XtNleft, XtChainLeft); j++; XtSetArg(args[j], XtNright, XtChainLeft); j++; - b_clas= XtCreateManagedWidget(_("classical"), commandWidgetClass, + XtSetArg(args[j], XtNstate, tcInc==0); j++; + b_clas= XtCreateManagedWidget(_("classical"), toggleWidgetClass, form, args, j); XtAddCallback(b_clas, XtNcallback, TimeControlCallback, (XtPointer) 0); j=0; + XtSetArg(args[j], XtNradioGroup, b_clas); j++; XtSetArg(args[j], XtNfromVert, tcOdds1); j++; XtSetArg(args[j], XtNfromHoriz, b_clas); j++; XtSetArg(args[j], XtNbottom, XtChainBottom); j++; XtSetArg(args[j], XtNtop, XtChainBottom); j++; XtSetArg(args[j], XtNleft, XtChainLeft); j++; XtSetArg(args[j], XtNright, XtChainLeft); j++; - b_inc = XtCreateManagedWidget(_("incremental"), commandWidgetClass, + XtSetArg(args[j], XtNstate, tcInc==1); j++; + b_inc = XtCreateManagedWidget(_("incremental"), toggleWidgetClass, + form, args, j); + XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0); + + j=0; + XtSetArg(args[j], XtNradioGroup, b_inc); j++; + XtSetArg(args[j], XtNfromVert, tcOdds1); j++; + XtSetArg(args[j], XtNfromHoriz, b_inc); j++; + XtSetArg(args[j], XtNbottom, XtChainBottom); j++; + XtSetArg(args[j], XtNtop, XtChainBottom); j++; + XtSetArg(args[j], XtNleft, XtChainLeft); j++; + XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNstate, tcInc==2); j++; + b_inc = XtCreateManagedWidget(_("fixed time"), toggleWidgetClass, form, args, j); XtAddCallback(b_inc, XtNcallback, TimeControlCallback, (XtPointer) 0); @@ -567,6 +620,7 @@ Widget engDrawMoves, engThreshold, engRule, engRepeat; void EnginePopDown() { if (!EngineUp) return; + previous = NULL; XtPopdown(EngineShell); XtDestroyWidget(EngineShell); EngineUp = False; @@ -602,8 +656,8 @@ void EngineCallback(w, client_data, call_data) // read all switches appData.periodicUpdates = ReadToggle(w1); // appData.hideThinkingFromHuman = ReadToggle(w2); - appData.firstScoreIsAbsolute = ReadToggle(w3); - appData.secondScoreIsAbsolute = ReadToggle(w4); + first.scoreIsAbsolute = appData.firstScoreIsAbsolute = ReadToggle(w3); + second.scoreIsAbsolute = appData.secondScoreIsAbsolute = ReadToggle(w4); appData.testClaims = ReadToggle(w5); appData.checkMates = ReadToggle(w6); appData.materialDraws = ReadToggle(w7); @@ -693,7 +747,7 @@ void EnginePopUp() XtSetArg(args[j-3], XtNstate, appData.secondScoreIsAbsolute); w4 = XtCreateManagedWidget(_("Engine #2 Score is Absolute"), toggleWidgetClass, form, args, j); - s1 = XtCreateManagedWidget(_("\nEngine-Engine Adjudications:"), labelWidgetClass, form, args, 3); + s1 = XtCreateManagedWidget(_("\nAdjudications in non-ICS games:"), labelWidgetClass, form, args, 3); XtSetArg(args[j-1], XtNfromVert, (XtArgVal) s1); XtSetArg(args[j-3], XtNstate, appData.testClaims); @@ -907,6 +961,7 @@ struct NewVarButton buttonDesc[] = { {N_("berolina"), "#FFFFFF", 0, VariantBerolina}, {N_("cylinder"), "#FFFFFF", 0, VariantCylinder}, {N_("shatranj"), "#FFFFFF", 0, VariantShatranj}, + {N_("makruk"), "#FFFFFF", 0, VariantMakruk}, {N_("atomic"), "#FFFFFF", 0, VariantAtomic}, {N_("two kings"), "#FFFFFF", 0, VariantTwoKings}, {N_("3-checks"), "#FFFFFF", 0, Variant3Check}, @@ -1125,6 +1180,7 @@ struct UciControl controlDesc[] = { void UciPopDown() { if (!UciUp) return; + previous = NULL; XtPopdown(UciShell); XtDestroyWidget(UciShell); UciUp = False; @@ -1323,6 +1379,7 @@ ChessProgramState *currentCps; void SettingsPopDown() { if (!SettingsUp) return; + previous = NULL; XtPopdown(SettingsShell); XtDestroyWidget(SettingsShell); SettingsUp = False; @@ -1478,10 +1535,11 @@ void SettingsPopUp(ChessProgramState *cps) Widget popup, layout, dialog, edit=NULL, form, oldform, last, b_ok, b_cancel, leftMargin = NULL; Window root, child; int x, y, i, j, height, width, h, c; - int win_x, win_y; + int win_x, win_y, maxWidth, maxTextWidth; unsigned int mask; char def[80], *p, *q; static char pane[6] = "paneX"; + Widget texts[100], forelast = NULL, anchor, widest; // to do: start up second engine if needed if(!cps->initDone || !cps->nrOptions) return; // nothing to be done @@ -1508,8 +1566,9 @@ void SettingsPopUp(ChessProgramState *cps) XtSetValues(form, args, j); leftMargin = form; - last = NULL; + last = widest = NULL; anchor = forelast; for(h=0; h= cps->nrOptions) break; switch(cps->option[i].type) { @@ -1520,12 +1579,13 @@ void SettingsPopUp(ChessProgramState *cps) XtSetArg(args[j], XtNfromVert, last); j++; XtSetArg(args[j], XtNborderWidth, 0); j++; XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++; + texts[h] = dialog = XtCreateManagedWidget(cps->option[i].name, labelWidgetClass, form, args, j); j=0; XtSetArg(args[j], XtNfromVert, last); j++; XtSetArg(args[j], XtNfromHoriz, dialog); j++; XtSetArg(args[j], XtNborderWidth, 1); j++; - XtSetArg(args[j], XtNwidth, cps->option[i].type == Spin ? 40 : 100); j++; + XtSetArg(args[j], XtNwidth, cps->option[i].type == Spin ? 40 : 175); j++; XtSetArg(args[j], XtNeditType, XawtextEdit); j++; XtSetArg(args[j], XtNuseStringInPlace, False); j++; XtSetArg(args[j], XtNdisplayCaret, False); j++; @@ -1578,7 +1638,7 @@ void SettingsPopUp(ChessProgramState *cps) XtSetArg(args[j], XtNfromVert, last); j++; XtSetArg(args[j], XtNstate, cps->option[i].value); j++; cps->option[i].handle = (void*) - (last = XtCreateManagedWidget(cps->option[i].name, commandWidgetClass, form, args, j)); + (dialog = last = XtCreateManagedWidget(cps->option[i].name, commandWidgetClass, form, args, j)); XtAddCallback(last, XtNcallback, SettingsCallback, (XtPointer)(intptr_t) (cps->option[i].type == SaveButton)); break; @@ -1602,17 +1662,54 @@ void SettingsPopUp(ChessProgramState *cps) break; } } + + // make an attempt to align all spins and textbox controls + maxWidth = maxTextWidth = 0; + for(h=0; h= cps->nrOptions) break; + if(cps->option[i].type == Spin || cps->option[i].type == TextBox) { + Dimension w; + j=0; + XtSetArg(args[j], XtNwidth, &w); j++; + XtGetValues(texts[h], args, j); + if(cps->option[i].type == Spin) { + if(w > maxWidth) maxWidth = w; + widest = texts[h]; + } else { + if(w > maxTextWidth) maxTextWidth = w; + if(!widest) widest = texts[h]; + } + } + } + if(maxTextWidth + 110 < maxWidth) + maxTextWidth = maxWidth - 110; + else maxWidth = maxTextWidth + 110; + for(h=0; h= cps->nrOptions) break; + j=0; + if(cps->option[i].type == Spin) { + XtSetArg(args[j], XtNwidth, maxWidth); j++; + XtSetValues(texts[h], args, j); + } else + if(cps->option[i].type == TextBox) { + XtSetArg(args[j], XtNwidth, maxTextWidth); j++; + XtSetValues(texts[h], args, j); + } + } } j=0; - XtSetArg(args[j], XtNfromVert, last); j++; + XtSetArg(args[j], XtNfromVert, anchor ? anchor : last); j++; XtSetArg(args[j], XtNbottom, XtChainBottom); j++; XtSetArg(args[j], XtNtop, XtChainBottom); j++; - XtSetArg(args[j], XtNleft, XtChainLeft); j++; - XtSetArg(args[j], XtNright, XtChainLeft); j++; + XtSetArg(args[j], XtNleft, XtChainRight); j++; + XtSetArg(args[j], XtNright, XtChainRight); j++; + XtSetArg(args[j], XtNfromHoriz, widest ? widest : dialog); j++; b_ok = XtCreateManagedWidget(_("OK"), commandWidgetClass, form, args, j); XtAddCallback(b_ok, XtNcallback, SettingsCallback, (XtPointer) 0); - XtSetArg(args[j], XtNfromHoriz, b_ok); j++; + XtSetArg(args[j-1], XtNfromHoriz, b_ok); b_cancel = XtCreateManagedWidget(_("cancel"), commandWidgetClass, form, args, j); XtAddCallback(b_cancel, XtNcallback, SettingsPopDown, (XtPointer) 0);