2 * xhistory.c -- Move list window, part of X front end for XBoard
5 * Copyright 2000,2009 Free Software Foundation, Inc.
6 * ------------------------------------------------------------------------
8 * GNU XBoard is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or (at
11 * your option) any later version.
13 * GNU XBoard is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see http://www.gnu.org/licenses/. *
21 *------------------------------------------------------------------------
22 ** See the file ChangeLog for a revision history. */
29 #include <sys/types.h>
34 #else /* not STDC_HEADERS */
35 extern char *getenv();
38 # else /* not HAVE_STRING_H */
40 # endif /* not HAVE_STRING_H */
41 #endif /* not STDC_HEADERS */
47 #include <X11/Intrinsic.h>
48 #include <X11/StringDefs.h>
49 #include <X11/Shell.h>
50 #include <X11/Xaw/Dialog.h>
51 #include <X11/Xaw/Form.h>
52 #include <X11/Xaw/List.h>
53 #include <X11/Xaw/Label.h>
54 #include <X11/Xaw/SimpleMenu.h>
55 #include <X11/Xaw/SmeBSB.h>
56 #include <X11/Xaw/SmeLine.h>
57 #include <X11/Xaw/Box.h>
58 #include <X11/Xaw/Paned.h>
59 #include <X11/Xaw/MenuButton.h>
60 #include <X11/cursorfont.h>
61 #include <X11/Xaw/Text.h>
62 #include <X11/Xaw/AsciiText.h>
63 #include <X11/Xaw/Viewport.h>
73 # define _(s) gettext (s)
74 # define N_(s) gettext_noop (s)
82 extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
83 extern Display *xDisplay;
84 extern int squareSize;
85 extern Pixmap xMarkPixmap;
86 extern char *layoutName;
89 String *Nr,*white,*black;
90 int aNr; /* space actually alocated */
91 Widget mvn,mvw,mvb,vbox,viewport,sh;
95 struct History *hist=0;
97 Position gameHistoryX, gameHistoryY;
100 HistoryPopDown(w, client_data, call_data)
102 XtPointer client_data, call_data;
107 // [HGM] remember old position
109 XtSetArg(args[j], XtNx, &gameHistoryX); j++;
110 XtSetArg(args[j], XtNy, &gameHistoryY); j++;
111 XtGetValues(hist->sh, args, j);
117 XtSetArg(args[j], XtNleftBitmap, None); j++;
118 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Move History"),
122 void HistoryMoveProc(Widget w, XtPointer closure, XtPointer call_data)
125 XawListReturnStruct *R = (XawListReturnStruct *) call_data;
126 if (w == hist->mvn || w == hist->mvw) {
127 to=2*R->list_index-1;
130 else if (w == hist->mvb) {
136 void HistoryAlloc(int len){
139 free(hist->Nr[0]);free(hist->white[0]);free(hist->black[0]);
140 free(hist->Nr);free(hist->white);free(hist->black);
143 hist=(struct History*)malloc(sizeof(struct History));
146 hist->Nr=(String*)malloc(hist->aNr*sizeof(String*));
147 hist->white=(String*)malloc(hist->aNr*sizeof(String*));
148 hist->black=(String*)malloc(hist->aNr*sizeof(String*));
150 hist->Nr[0]=(String)malloc(hist->aNr*6);
151 hist->white[0]=(String)malloc(hist->aNr*MOVE_LEN);
152 hist->black[0]=(String)malloc(hist->aNr*MOVE_LEN);
154 sprintf(hist->Nr[0]," ");
155 sprintf(hist->white[0],_("White "));
156 sprintf(hist->black[0],_("Black "));
157 for(i=1;i<hist->aNr;i++){
158 hist->Nr[i]= hist->Nr[i-1]+6;
159 hist->white[i]= hist->white[i-1]+MOVE_LEN;
160 hist->black[i]= hist->black[i-1]+MOVE_LEN;
161 sprintf(hist->Nr[i],"%i.",i);
162 sprintf(hist->white[i],"-----");
163 sprintf(hist->black[i],"-----");
169 /* Find empty space inside vbox form widget and redistribute it amongst
170 the list widgets inside it. */
171 /* This version sort of works */
182 XtSetArg(args[j], XtNx, &x); j++;
183 XtSetArg(args[j], XtNwidth, &w); j++;
184 XtSetArg(args[j], XtNborderWidth, &bw); j++;
185 XtGetValues(hist->mvb, args, j);
189 XtSetArg(args[j], XtNwidth, &w); j++;
190 XtSetArg(args[j], XtNdefaultDistance, &dd); j++;
191 XtGetValues(hist->vbox, args, j);
196 extra = -((-extra)/2);
202 XtSetArg(args[j], XtNwidth, &w); j++;
203 XtGetValues(hist->mvw, args, j);
206 XtSetArg(args[j], XtNwidth, w); j++;
207 XtSetValues(hist->mvw, args, j);
210 XtSetArg(args[j], XtNwidth, &w); j++;
211 XtGetValues(hist->mvb, args, j);
214 XtSetArg(args[j], XtNwidth, w); j++;
215 XtSetValues(hist->mvb, args, j);
218 /* Find empty space inside vbox form widget and redistribute it amongst
219 the list widgets inside it. */
220 /* This version doesn't work */
225 Dimension fw, niw, wiw, biw, nbw, wbw, bbw;
226 int j, nl, wl, bl, fdd;
230 XtSetArg(args[j], XtNwidth, &fw); j++;
231 XtSetArg(args[j], XtNdefaultDistance, &fdd); j++;
232 XtGetValues(hist->vbox, args, j);
235 XtSetArg(args[j], XtNlongest, &nl); j++;
236 XtSetArg(args[j], XtNinternalWidth, &niw); j++;
237 XtSetArg(args[j], XtNborderWidth, &nbw); j++;
238 XtGetValues(hist->mvn, args, j);
241 XtSetArg(args[j], XtNlongest, &wl); j++;
242 XtSetArg(args[j], XtNinternalWidth, &wiw); j++;
243 XtSetArg(args[j], XtNborderWidth, &wbw); j++;
244 XtGetValues(hist->mvw, args, j);
247 XtSetArg(args[j], XtNlongest, &bl); j++;
248 XtSetArg(args[j], XtNinternalWidth, &biw); j++;
249 XtSetArg(args[j], XtNborderWidth, &bbw); j++;
250 XtGetValues(hist->mvb, args, j);
253 nl - 1 - 2*niw - 2*nbw - wl - 2*wiw - 2*wbw - bl - 2*biw - 2*bbw;
254 if (extra < 0) extra = 0;
257 XtSetArg(args[j], XtNwidth, nl + 1 + 2*niw); j++;
258 XtSetValues(hist->mvn, args, j);
261 XtSetArg(args[j], XtNwidth, wl + 2*wiw + extra/2); j++;
262 XtSetValues(hist->mvw, args, j);
265 XtSetArg(args[j], XtNwidth, bl + 2*biw + extra/2); j++;
266 XtSetValues(hist->mvb, args, j);
270 void HistorySet(char movelist[][2*MOVE_LEN],int first,int last,int current){
273 if(last >= hist->aNr) HistoryAlloc(last+_LL_);
274 for(i=0;i<last;i++) {
277 char* p = strchr(movelist[i], ' ');
279 strncpy(hist->white[i/2+1], movelist[i], p-movelist[i]);
280 hist->white[i/2+1][p-movelist[i]] = NULLCHAR;
282 strcpy(hist->white[i/2+1],movelist[i]);
285 strcpy(hist->white[i/2+1],dots);
289 char* p = strchr(movelist[i], ' ');
291 strncpy(hist->black[i/2+1], movelist[i], p-movelist[i]);
292 hist->black[i/2+1][p-movelist[i]] = NULLCHAR;
294 strcpy(hist->black[i/2+1],movelist[i]);
297 strcpy(hist->black[i/2+1],"");
301 strcpy(hist->black[last/2+1],"");
304 XawFormDoLayout(hist->vbox, False);
305 XawListChange(hist->mvn,hist->Nr+b,m,0,True);
306 XawListChange(hist->mvw,hist->white+b,m,0,True);
307 XawListChange(hist->mvb,hist->black+b,m,0,True);
309 XawFormDoLayout(hist->vbox, True);
311 XawListUnhighlight(hist->mvw);
312 XawListUnhighlight(hist->mvb);
314 else if((current%2)==0){
315 XawListHighlight(hist->mvw, current/2+1);
316 XawListUnhighlight(hist->mvb);
319 XawListUnhighlight(hist->mvw);
320 if(current) XawListHighlight(hist->mvb, current/2+1);
321 else XawListUnhighlight(hist->mvb);
326 Widget HistoryCreate()
331 Widget layout,form,b_close;
333 "<Key>Up: BackwardProc() \n \
334 <Key>Left: BackwardProc() \n \
335 <Key>Down: ForwardProc() \n \
336 <Key>Right: ForwardProc() \n";
337 /*--- allocate memory for move-strings ---*/
340 /*-------- create the widgets ---------------*/
342 XtSetArg(args[j], XtNresizable, True); j++;
343 XtSetArg(args[j], XtNallowShellResize, True); j++;
346 XtCreatePopupShell(_("Move list"), topLevelShellWidgetClass,
347 shellWidget, args, j);
350 XtCreatePopupShell(_("Move list"), transientShellWidgetClass,
351 shellWidget, args, j);
354 XtSetArg(args[j], XtNborderWidth, 0); j++;
355 XtSetArg(args[j], XtNdefaultDistance, 0); j++;
357 XtCreateManagedWidget(layoutName, formWidgetClass, hist->sh,
361 XtSetArg(args[j], XtNborderWidth, 0); j++;
362 XtSetArg(args[j], XtNresizable, True); j++;
365 XtCreateManagedWidget("form", formWidgetClass, layout, args, j);
370 XtSetArg(args[j], XtNtop, XtChainTop); j++;
371 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
372 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
373 XtSetArg(args[j], XtNright, XtChainRight); j++;
375 XtSetArg(args[j], XtNborderWidth, 1); j++;
376 XtSetArg(args[j], XtNresizable, False); j++;
377 XtSetArg(args[j], XtNallowVert, True); j++;
378 XtSetArg(args[j], XtNallowHoriz, True); j++;
379 XtSetArg(args[j], XtNforceBars, False); j++;
380 XtSetArg(args[j], XtNheight, 280); j++;
382 XtCreateManagedWidget("viewport", viewportWidgetClass,
385 XtSetArg(args[j], XtNborderWidth, 0); j++;
386 XtSetArg(args[j], XtNorientation,XtorientHorizontal);j++;
388 XtCreateManagedWidget("vbox", formWidgetClass, hist->viewport, args, j);
391 XtSetArg(args[j], XtNtop, XtChainTop); j++;
392 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
393 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
394 XtSetArg(args[j], XtNright, XtChainLeft); j++;
396 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
397 XtSetArg(args[j], XtNforceColumns, True); j++;
398 XtSetArg(args[j], XtNverticalList, True); j++;
399 XtSetArg(args[j], XtNborderWidth, 0); j++;
400 XtSetArg(args[j], XtNresizable,True);j++;
401 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
402 hist->mvn = XtCreateManagedWidget("movesn", listWidgetClass,
403 hist->vbox, args, j);
404 XtAddCallback(hist->mvn, XtNcallback, HistoryMoveProc, (XtPointer) hist);
407 XtSetArg(args[j], XtNtop, XtChainTop); j++;
408 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
409 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
410 XtSetArg(args[j], XtNright, XtRubber); j++;
412 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
413 XtSetArg(args[j], XtNforceColumns, True); j++;
414 XtSetArg(args[j], XtNverticalList, True); j++;
415 XtSetArg(args[j], XtNborderWidth, 0); j++;
416 XtSetArg(args[j], XtNresizable,True);j++;
417 XtSetArg(args[j], XtNfromHoriz, hist->mvn); j++;
418 hist->mvw = XtCreateManagedWidget("movesw", listWidgetClass,
419 hist->vbox, args, j);
420 XtAddCallback(hist->mvw, XtNcallback, HistoryMoveProc, (XtPointer) hist);
423 XtSetArg(args[j], XtNtop, XtChainTop); j++;
424 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
425 XtSetArg(args[j], XtNleft, XtRubber); j++;
426 XtSetArg(args[j], XtNright, XtRubber); j++;
428 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
429 XtSetArg(args[j], XtNforceColumns, True); j++;
430 XtSetArg(args[j], XtNverticalList, True); j++;
431 XtSetArg(args[j], XtNborderWidth, 0); j++;
432 XtSetArg(args[j], XtNresizable,True);j++;
433 XtSetArg(args[j], XtNfromHoriz, hist->mvw); j++;
434 hist->mvb = XtCreateManagedWidget("movesb", listWidgetClass,
435 hist->vbox, args, j);
436 XtAddCallback(hist->mvb, XtNcallback, HistoryMoveProc, (XtPointer) hist);
439 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
440 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
441 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
442 XtSetArg(args[j], XtNright, XtChainLeft); j++;
443 XtSetArg(args[j], XtNfromVert, hist->viewport); j++;
444 b_close= XtCreateManagedWidget(_("Close"), commandWidgetClass,
446 XtAddCallback(b_close, XtNcallback, HistoryPopDown, (XtPointer) 0);
448 XtAugmentTranslations(hist->sh,XtParseTranslationTable (trstr));
450 XtRealizeWidget(hist->sh);
451 CatchDeleteWindow(hist->sh, "HistoryPopDown");
453 for(i=1;i<hist->aNr;i++){
454 strcpy(hist->white[i],dots);
455 strcpy(hist->black[i],"");
467 if(!hist) HistoryCreate();
469 XtPopup(hist->sh, XtGrabNone);
471 // [HGM] restore old position
473 XtSetArg(args[j], XtNx, gameHistoryX); j++;
474 XtSetArg(args[j], XtNy, gameHistoryY); j++;
475 XtSetValues(hist->sh, args, j);
478 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
479 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Move History"),
486 HistoryShowProc(w, event, prms, nprms)
495 } else if (hist->Up) {
496 HistoryPopDown(0,0,0);
500 ToNrEvent(currentMove);