//--------------------------- Engine-specific options menu ----------------------------------
int dialogError;
-static Boolean browserUp;
Option *dialogOptions[NrOfDialogs];
+static Arg layoutArgs[] = {
+ { XtNborderWidth, 0 },
+ { XtNdefaultDistance, 0 },
+};
+
+static Arg formArgs[] = {
+ { XtNborderWidth, 0 },
+ { XtNresizable, (XtArgVal) True },
+};
+
void
GetWidgetText (Option *opt, char **buf)
{
float top, bottom, f, g;
HighlightListBoxItem(opt, sel);
if(!ReadScroll(opt, &top, &bottom)) return; // no scroll bar
- bottom = bottom*max - 1.;
+ bottom = bottom*max - 1.f;
f = g = top;
top *= max;
- if(sel > (top + 3*bottom)/4) f = (sel - 0.75*(bottom-top))/max; else
- if(sel < (3*top + bottom)/4) f = (sel - 0.25*(bottom-top))/max;
- if(f < 0.) f = 0.; if(f + 1./max > 1.) f = 1. - 1./max;
+ if(sel > (top + 3*bottom)/4) f = (sel - 0.75f*(bottom-top))/max; else
+ if(sel < (3*top + bottom)/4) f = (sel - 0.25f*(bottom-top))/max;
+ if(f < 0.f) f = 0.; if(f + 1.f/max > 1.f) f = 1. - 1./max;
if(f != g) SetScroll(opt, f);
}
for(r = ""; *q; q++) if(*q == '.') r = q; else if(*q == '/') r = ""; // last dot after last slash
if(!strcmp(r, "") && !currentCps && opt->type == FileName && opt->textValue)
r = opt->textValue;
- browserUp = True;
- if(XsraSelFile(shells[TransientDlg], opt->name, NULL, NULL, "", "", r,
- opt->type == PathName ? "p" : "f", NULL, &p)) {
- int len = strlen(p);
- if(len && p[len-1] == '/') p[len-1] = NULLCHAR;
- XtSetArg(args[0], XtNstring, p);
- XtSetValues(opt->handle, args, 1);
- }
- browserUp = False;
- SetFocus(opt->handle, shells[TransientDlg], (XEvent*) NULL, False);
+ Browse(data>>8, opt->name, NULL, r, opt->type == PathName, "", &p, (FILE**) opt);
return;
} else
if (strcmp(name, "+") == 0) {
values[i] = j; // store selected value in Option struct, for retrieval at OK
- if(opt[i].type == Graph || opt[i].min & COMBO_CALLBACK && !currentCps) {
+ if(opt[i].type == Graph || opt[i].min & COMBO_CALLBACK && (!currentCps || shellUp[BrowserDlg])) {
((ButtonCallback*) opt[i].target)(i);
return;
}
static Widget
CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def)
{ // fromList determines if the item texts are taken from a list of strings, or from a menu table
- int i, j;
+ int i;
Widget menu, entry;
Arg arg;
MenuItem *mb = (MenuItem *) opt->choice;
for (i=0; 1; i++)
{
- char *msg = fromList ? list[i] : mb[i].string, *msg2;
+ char *msg = fromList ? list[i] : mb[i].string;
if(!msg) break;
entry = CreateMenuItem(menu, opt->min & NO_GETTEXT ? msg : _(msg), (XtCallbackProc) ComboSelect, (n<<16)+i);
if(!fromList) mb[i].handle = (void*) entry; // save item ID, for enabling / checkmarking
"<Key>Escape: TypeInProc(0) \n";
extern char filterTranslations[];
extern char gameListTranslations[];
+extern char memoTranslations[];
-char *translationTable[] = {
+char *translationTable[] = { // beware: order is essential!
historyTranslations, commentTranslations, moveTypeInTranslations, ICSInputTranslations,
- filterTranslations, gameListTranslations,
+ filterTranslations, gameListTranslations, memoTranslations
};
void
Widget shells[NrOfDialogs];
DialogClass parents[NrOfDialogs];
WindowPlacement *wp[NrOfDialogs] = { // Beware! Order must correspond to DialogClass enum
- NULL, &wpComment, &wpTags, NULL, NULL, NULL, NULL, &wpMoveHistory, &wpGameList, &wpEngineOutput
+ NULL, &wpComment, &wpTags, NULL, NULL, NULL, NULL, &wpMoveHistory, &wpGameList, &wpEngineOutput, &wpEvalGraph,
+ NULL, NULL, NULL, NULL, &wpMain
};
int
return shells[n] != NULL;
}
+void
+RaiseWindow (DialogClass dlg)
+{
+ static XEvent xev;
+ Window root = RootWindow(xDisplay, DefaultScreen(xDisplay));
+ Atom atom = XInternAtom (xDisplay, "_NET_ACTIVE_WINDOW", False);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = xDisplay;
+ xev.xclient.window = XtWindow(shells[dlg]);
+ xev.xclient.message_type = atom;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = CurrentTime;
+
+ XSendEvent (xDisplay,
+ root, False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+
+ XFlush(xDisplay);
+ XSync(xDisplay, False);
+}
+
int
PopDown (DialogClass n)
{ // pops down any dialog created by GenericPopUp (or returns False if it wasn't up), unmarks any associated marked menu
MarkMenuItem(marked[n], False);
marked[n] = NULL;
}
- if(!n) currentCps = NULL; // if an Engine Settings dialog was up, we must be popping it down now
+ if(!n && n != BrowserDlg) currentCps = NULL; // if an Engine Settings dialog was up, we must be popping it down now
currentOption = dialogOptions[TransientDlg]; // just in case a transient dialog was up (to allow its check and combo callbacks to work)
- XtSetKeyboardFocus(shells[parents[n]], n == BoardWindow ? formWidget: shells[parents[n]]);
+ RaiseWindow(parents[n]);
+ if(parents[n] == BoardWindow) XtSetKeyboardFocus(shellWidget, formWidget);
return 1;
}
{ // to cause popdown through a translation (Delete Window button!)
int dlg = atoi(prms[0]);
Widget sh = shells[dlg];
- if(browserUp || dialogError) return; // prevent closing dialog when it has an open file-browse daughter
+ if(shellUp[BrowserDlg] && dlg != BrowserDlg || dialogError) return; // prevent closing dialog when it has an open file-browse daughter
shells[dlg] = w;
PopDown(dlg);
shells[dlg] = sh; // restore
if(GenericReadout(currentOption, -1)) PopDown(dlg); // calls OK-proc after full readout, but no popdown if it returns false
} else
- if(currentCps) {
+ if(currentCps && dlg != BrowserDlg) {
XtSetArg(args[0], XtNlabel, &name);
XtGetValues(w, args, 1);
if(currentOption[data].type == SaveButton) GenericReadout(currentOption, -1);
int j=0, n = atoi(prms[0]);
static char *params[3] = { "", "Continuous", "Proportional" };
Arg args[16];
- float f, h, top;
+ float h, top;
Widget v;
if(!n) { // transient dialogs also use this for list-selection callback
n = prms[1][0]-'0';
XtSetArg(args[j], XtNshown, &h); j++;
XtSetArg(args[j], XtNtopOfThumb, &top); j++;
XtGetValues(v, args, j);
- top += 0.1*h*n; if(top < 0.) top = 0.;
+ top += 0.1f*h*n; if(top < 0.f) top = 0.;
XtCallActionProc(v, "StartScroll", event, params+1, 1);
XawScrollbarSetThumb(v, top, -1.0);
XtCallActionProc(v, "NotifyThumb", event, params, 0);
static void
SqueezeIntoBox (Option *opt, int nr, int width)
{ // size buttons in bar to fit, clipping button names where necessary
- int i, j, wtot = 0;
+ int i, wtot = 0;
Dimension widths[20], oldWidths[20];
Arg arg;
for(i=1; i<nr; i++) {
// set size (if given)
if(w) XtSetArg(args[j], XtNwidth, w), j++;
if(h) XtSetArg(args[j], XtNheight, h), j++;
+ // color
+ if(!appData.monoMode) {
+ if(!b && appData.dialogColor[0]) XtSetArg(args[j], XtNbackground, dialogColor), j++;
+ if(b == 3 && appData.buttonColor[0]) XtSetArg(args[j], XtNbackground, buttonColor), j++;
+ if(b == 3) b = 1;
+ }
// border
XtSetArg(args[j], XtNborderWidth, b); j++;
return j;
}
int
-GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent, int modal)
+GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent, int modal, int top)
{
Arg args[24];
Widget popup, layout, dialog=NULL, edit=NULL, form, last, b_ok, b_cancel, previousPane = NULL, textField = NULL, oldForm, oldLastRow, oldForeLast;
int x, y, i, j, height=999, width=1, h, c, w, shrink=FALSE, stack = 0, box, chain;
int win_x, win_y, maxWidth, maxTextWidth;
unsigned int mask;
- char def[MSG_SIZ], *msg;
+ char def[MSG_SIZ], *msg, engineDlg = (currentCps != NULL && dlgNr != BrowserDlg);
static char pane[6] = "paneX";
Widget texts[100], forelast = NULL, anchor, widest, lastrow = NULL, browse = NULL;
- Dimension bWidth = 50, m;
+ Dimension bWidth = 50;
if(dlgNr < PromoDlg && shellUp[dlgNr]) return 0; // already up
if(dlgNr && dlgNr < PromoDlg && shells[dlgNr]) { // reusable, and used before (but popped down)
// WARNING: this kludge does not work for persistent dialogs, so that these cannot have spin or combo controls!
currentOption = option;
- if(currentCps) { // Settings popup for engine: format through heuristic
+ if(engineDlg) { // Settings popup for engine: format through heuristic
int n = currentCps->nrOptions;
if(!n) { DisplayNote(_("Engine has no options")); currentCps = NULL; return 0; }
if(n > 50) width = 4; else if(n>24) width = 2; else width = 1;
XtSetArg(args[i], XtNresizable, True); i++;
shells[BoardWindow] = shellWidget; parents[dlgNr] = parent;
+ if(dlgNr == BoardWindow) popup = shellWidget; else
popup = shells[dlgNr] =
-#if TOPLEVEL
- XtCreatePopupShell(title, modal ? transientShellWidgetClass : topLevelShellWidgetClass,
-#else
- XtCreatePopupShell(title, transientShellWidgetClass,
-#endif
+ XtCreatePopupShell(title, !top || !appData.topLevel ? transientShellWidgetClass : topLevelShellWidgetClass,
shells[parent], args, i);
layout =
XtCreateManagedWidget(layoutName, formWidgetClass, popup,
layoutArgs, XtNumber(layoutArgs));
+ if(!appData.monoMode && appData.dialogColor[0]) XtSetArg(args[0], XtNbackground, dialogColor);
+ XtSetValues(layout, args, 1);
+
for(c=0; c<width; c++) {
pane[4] = 'A'+c;
form =
formArgs, XtNumber(formArgs));
j=0;
XtSetArg(args[j], stack ? XtNfromVert : XtNfromHoriz, previousPane); j++;
+ if(!appData.monoMode && appData.dialogColor[0]) XtSetArg(args[j], XtNbackground, dialogColor), j++;
XtSetValues(form, args, j);
lastrow = forelast = NULL;
previousPane = form;
option[i].value = *(float*)option[i].target;
goto tBox;
case Spin:
- if(!currentCps) option[i].value = *(int*)option[i].target;
+ if(!engineDlg) option[i].value = *(int*)option[i].target;
snprintf(def, MSG_SIZ, "%d", option[i].value);
case TextBox:
case FileName:
if(option[i].type == FileName || option[i].type == PathName) w -= 55;
j = SetPositionAndSize(args, dialog, last, 1 /* border */,
w /* w */, option[i].type == TextBox ? option[i].value : 0 /* h */, 0x91 /* chain full width */);
- if(option[i].type == TextBox && option[i].value) { // decorations for multi-line text-edits
+ if(option[i].type == TextBox) { // decorations for multi-line text-edits
if(option[i].min & T_VSCRL) { XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways); j++; }
if(option[i].min & T_HSCRL) { XtSetArg(args[j], XtNscrollHorizontal, XawtextScrollAlways); j++; }
if(option[i].min & T_FILL) { XtSetArg(args[j], XtNautoFill, True); j++; }
if(option[i].min & T_WRAP) { XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++; }
- if(option[i].min & T_TOP) { XtSetArg(args[j], XtNtop, XtChainTop); j++; }
+ if(option[i].min & T_TOP) { XtSetArg(args[j], XtNtop, XtChainTop); j++;
+ if(!option[i].value) { XtSetArg(args[j], XtNbottom, XtChainTop); j++;
+ XtSetValues(dialog, args+j-2, 2);
+ }
+ }
} else shrink = TRUE;
XtSetArg(args[j], XtNeditType, XawtextEdit); j++;
XtSetArg(args[j], XtNuseStringInPlace, False); j++;
XtSetArg(args[j], XtNresizable, True); j++;
XtSetArg(args[j], XtNinsertPosition, 9999); j++;
XtSetArg(args[j], XtNstring, option[i].type==Spin || option[i].type==Fractional ? def :
- currentCps ? option[i].textValue : *(char**)option[i].target); j++;
+ engineDlg ? option[i].textValue : *(char**)option[i].target); j++;
edit = last;
option[i].handle = (void*)
(textField = last = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j));
} else {
w = 20; msg = "+"; j = textHeight/2; // spin button
}
- j = SetPositionAndSize(args, last, edit, 1 /* border */,
+ j = SetPositionAndSize(args, last, edit, 3 /* border */,
w /* w */, j /* h */, 0x31 /* chain to right edge */);
edit = XtCreateManagedWidget(msg, commandWidgetClass, form, args, j);
XtAddCallback(edit, XtNcallback, SpinCallback, (XtPointer)(intptr_t) i + 256*dlgNr);
if(option[i].type != Spin) break;
- j = SetPositionAndSize(args, last, edit, 1 /* border */,
+ j = SetPositionAndSize(args, last, edit, 3 /* border */,
20 /* w */, textHeight/2 /* h */, 0x31 /* chain to right edge */);
XtSetArg(args[j], XtNvertDistance, -1); j++;
last = XtCreateManagedWidget("-", commandWidgetClass, form, args, j);
XtAddCallback(last, XtNcallback, SpinCallback, (XtPointer)(intptr_t) i + 256*dlgNr);
break;
case CheckBox:
- if(!currentCps) option[i].value = *(Boolean*)option[i].target; // where checkbox callback uses it
+ if(!engineDlg) option[i].value = *(Boolean*)option[i].target; // where checkbox callback uses it
j = SetPositionAndSize(args, last, lastrow, 1 /* border */,
textHeight/2 /* w */, textHeight/2 /* h */, 0xC0 /* chain both to left edge */);
XtSetArg(args[j], XtNvertDistance, (textHeight+2)/4 + 3); j++;
chain = 0x31; // 0011.0001 = both left and right side to right edge
forelast = lastrow;
} else chain = 0, shrink = FALSE;
- j = SetPositionAndSize(args, last, lastrow, 1 /* border */,
- option[i].max /* w */, shrink ? textHeight : 0 /* h */, chain /* chain */);
+ j = SetPositionAndSize(args, last, lastrow, 3 /* border */,
+ option[i].max /* w */, shrink ? textHeight : 0 /* h */, option[i].min & 0xE | chain /* chain */);
XtSetArg(args[j], XtNlabel, _(option[i].name)); j++;
if(option[i].textValue) { // special for buttons of New Variant dialog
XtSetArg(args[j], XtNsensitive, appData.noChessProgram || option[i].value < 0
}
option[i].handle = (void*)
(dialog = last = XtCreateManagedWidget(option[i].name, commandWidgetClass, form, args, j));
- if(option[i].choice && ((char*)option[i].choice)[0] == '#' && !currentCps) { // for the color picker default-reset
+ if(option[i].choice && ((char*)option[i].choice)[0] == '#' && !engineDlg) { // for the color picker default-reset
SetColor( *(char**) option[i-1].target, &option[i]);
XtAddEventHandler(option[i-1].handle, KeyReleaseMask, False, ColorChanged, (XtPointer)(intptr_t) i-1);
}
texts[h] = dialog = XtCreateManagedWidget(option[i].name, labelWidgetClass, form, args, j);
if(option[i].min & COMBO_CALLBACK) msg = _(option[i].name); else {
- if(!currentCps) SetCurrentComboSelection(option+i);
+ if(!engineDlg) SetCurrentComboSelection(option+i);
msg=_(((char**)option[i].choice)[option[i].value]);
}
j = SetPositionAndSize(args, dialog, last, (option[i].min & 2) == 0 /* border */,
- option[i].max && !currentCps ? option[i].max : 100 /* w */,
+ option[i].max && !engineDlg ? option[i].max : 100 /* w */,
textHeight /* h */, 0x91 /* chain */); // same row as its label!
XtSetArg(args[j], XtNmenuName, XtNewString(option[i].name)); j++;
XtSetArg(args[j], XtNlabel, msg); j++;
(last = XtCreateManagedWidget("graph", widgetClass, form, args, j));
XtAddEventHandler(last, ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask, False,
(XtEventHandler) GraphEventProc, option[i].target); // mandatory user-supplied expose handler
+ if(option[i].min & SAME_ROW) last = forelast, forelast = lastrow;
break;
case PopUp: // note: used only after Graph, so 'last' refers to the Graph widget
option[i].handle = (void*) CreateComboPopup(last, option + i, i + 256*dlgNr, TRUE, option[i].value);
}
lastrow = forelast;
} else shrink = FALSE, lastrow = last, last = widest ? widest : dialog;
- j = SetPositionAndSize(args, last, anchor ? anchor : lastrow, 1 /* border */,
+ j = SetPositionAndSize(args, last, anchor ? anchor : lastrow, 3 /* border */,
0 /* w */, shrink ? textHeight : 0 /* h */, 0x37 /* chain: right, bottom and use both neighbors */);
if(!(option[i].min & NO_OK)) {
}
XtRealizeWidget(popup);
- XSetWMProtocols(xDisplay, XtWindow(popup), &wm_delete_window, 1);
- snprintf(def, MSG_SIZ, "<Message>WM_PROTOCOLS: GenericPopDown(\"%d\") \n", dlgNr);
- XtAugmentTranslations(popup, XtParseTranslationTable(def));
- XQueryPointer(xDisplay, xBoardWindow, &root, &child,
- &x, &y, &win_x, &win_y, &mask);
-
- XtSetArg(args[0], XtNx, x - 10);
- XtSetArg(args[1], XtNy, y - 30);
- XtSetValues(popup, args, 2);
-
+ if(dlgNr != BoardWindow) { // assign close button, and position w.r.t. pointer, if not main window
+ XSetWMProtocols(xDisplay, XtWindow(popup), &wm_delete_window, 1);
+ snprintf(def, MSG_SIZ, "<Message>WM_PROTOCOLS: GenericPopDown(\"%d\") \n", dlgNr);
+ XtAugmentTranslations(popup, XtParseTranslationTable(def));
+ XQueryPointer(xDisplay, xBoardWindow, &root, &child,
+ &x, &y, &win_x, &win_y, &mask);
+
+ XtSetArg(args[0], XtNx, x - 10);
+ XtSetArg(args[1], XtNy, y - 30);
+ XtSetValues(popup, args, 2);
+ }
XtPopup(popup, modal ? XtGrabExclusive : XtGrabNone);
shellUp[dlgNr]++; // count rather than flag
previous = NULL;
XtSetArg(args[j], XtNy, (Position) (wp[dlgNr]->y)); j++;
XtSetValues(popup, args, j);
}
+ RaiseWindow(dlgNr);
return 1; // tells caller he must do initialization (e.g. add specific event handlers)
}
XtSetArg(args[0], XtNinsertPosition, pos);
XtSetValues(opt->handle, args, 1);
// SetFocus(opt->handle, shells[InputBoxDlg], NULL, False); // No idea why this does not work, and the following is needed:
- XSetInputFocus(xDisplay, XtWindow(opt->handle), RevertToPointerRoot, CurrentTime);
+// XSetInputFocus(xDisplay, XtWindow(opt->handle), RevertToPointerRoot, CurrentTime);
}
void