2 * xhistory.c -- Move list window, part of X front end for XBoard
3 * $Id: xhistory.c,v 2.1 2003/10/27 19:21:00 mann Exp $
5 * Copyright 2000 Free Software Foundation, Inc.
7 * The following terms apply to the enhanced version of XBoard distributed
8 * by the Free Software Foundation:
9 * ------------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * ------------------------------------------------------------------------
25 * See the file ChangeLog for a revision history.
33 #include <sys/types.h>
38 #else /* not STDC_HEADERS */
39 extern char *getenv();
42 # else /* not HAVE_STRING_H */
44 # endif /* not HAVE_STRING_H */
45 #endif /* not STDC_HEADERS */
51 #include <X11/Intrinsic.h>
52 #include <X11/StringDefs.h>
53 #include <X11/Shell.h>
54 #include <X11/Xaw/Dialog.h>
55 #include <X11/Xaw/Form.h>
56 #include <X11/Xaw/List.h>
57 #include <X11/Xaw/Label.h>
58 #include <X11/Xaw/SimpleMenu.h>
59 #include <X11/Xaw/SmeBSB.h>
60 #include <X11/Xaw/SmeLine.h>
61 #include <X11/Xaw/Box.h>
62 #include <X11/Xaw/Paned.h>
63 #include <X11/Xaw/MenuButton.h>
64 #include <X11/cursorfont.h>
65 #include <X11/Xaw/Text.h>
66 #include <X11/Xaw/AsciiText.h>
67 #include <X11/Xaw/Viewport.h>
78 extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
79 extern Display *xDisplay;
80 extern int squareSize;
81 extern Pixmap xMarkPixmap;
82 extern char *layoutName;
85 String *Nr,*white,*black;
86 int aNr; /* space actually alocated */
87 Widget mvn,mvw,mvb,vbox,viewport,sh;
91 struct History *hist=0;
93 Position gameHistoryX, gameHistoryY;
95 HistoryPopDown(w, client_data, call_data)
97 XtPointer client_data, call_data;
102 // [HGM] remember old position
104 XtSetArg(args[j], XtNx, &gameHistoryX); j++;
\r
105 XtSetArg(args[j], XtNy, &gameHistoryY); j++;
\r
106 XtGetValues(hist->sh, args, j);
\r
112 XtSetArg(args[j], XtNleftBitmap, None); j++;
113 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Move History"),
117 void HistoryMoveProc(Widget w, XtPointer closure, XtPointer call_data)
121 XawListReturnStruct *R = (XawListReturnStruct *) call_data;
122 if (w == hist->mvn || w == hist->mvw) {
123 to=2*R->list_index-1;
126 else if (w == hist->mvb) {
132 void HistoryAlloc(int len){
135 free(hist->Nr[0]);free(hist->white[0]);free(hist->black[0]);
136 free(hist->Nr);free(hist->white);free(hist->black);
139 hist=(struct History*)malloc(sizeof(struct History));
142 hist->Nr=(String*)malloc(hist->aNr*sizeof(String*));
143 hist->white=(String*)malloc(hist->aNr*sizeof(String*));
144 hist->black=(String*)malloc(hist->aNr*sizeof(String*));
146 hist->Nr[0]=(String)malloc(hist->aNr*6);
147 hist->white[0]=(String)malloc(hist->aNr*MOVE_LEN);
148 hist->black[0]=(String)malloc(hist->aNr*MOVE_LEN);
150 sprintf(hist->Nr[0]," ");
151 sprintf(hist->white[0],"White ");
152 sprintf(hist->black[0],"Black ");
153 for(i=1;i<hist->aNr;i++){
154 hist->Nr[i]= hist->Nr[i-1]+6;
155 hist->white[i]= hist->white[i-1]+MOVE_LEN;
156 hist->black[i]= hist->black[i-1]+MOVE_LEN;
157 sprintf(hist->Nr[i],"%i.",i);
158 sprintf(hist->white[i],"-----");
159 sprintf(hist->black[i],"-----");
165 /* Find empty space inside vbox form widget and redistribute it amongst
166 the list widgets inside it. */
167 /* This version sort of works */
178 XtSetArg(args[j], XtNx, &x); j++;
179 XtSetArg(args[j], XtNwidth, &w); j++;
180 XtSetArg(args[j], XtNborderWidth, &bw); j++;
181 XtGetValues(hist->mvb, args, j);
185 XtSetArg(args[j], XtNwidth, &w); j++;
186 XtSetArg(args[j], XtNdefaultDistance, &dd); j++;
187 XtGetValues(hist->vbox, args, j);
192 extra = -((-extra)/2);
198 XtSetArg(args[j], XtNwidth, &w); j++;
199 XtGetValues(hist->mvw, args, j);
202 XtSetArg(args[j], XtNwidth, w); j++;
203 XtSetValues(hist->mvw, args, j);
206 XtSetArg(args[j], XtNwidth, &w); j++;
207 XtGetValues(hist->mvb, args, j);
210 XtSetArg(args[j], XtNwidth, w); j++;
211 XtSetValues(hist->mvb, args, j);
214 /* Find empty space inside vbox form widget and redistribute it amongst
215 the list widgets inside it. */
216 /* This version doesn't work */
221 Dimension fw, niw, wiw, biw, nbw, wbw, bbw;
222 int j, nl, wl, bl, fdd;
226 XtSetArg(args[j], XtNwidth, &fw); j++;
227 XtSetArg(args[j], XtNdefaultDistance, &fdd); j++;
228 XtGetValues(hist->vbox, args, j);
231 XtSetArg(args[j], XtNlongest, &nl); j++;
232 XtSetArg(args[j], XtNinternalWidth, &niw); j++;
233 XtSetArg(args[j], XtNborderWidth, &nbw); j++;
234 XtGetValues(hist->mvn, args, j);
237 XtSetArg(args[j], XtNlongest, &wl); j++;
238 XtSetArg(args[j], XtNinternalWidth, &wiw); j++;
239 XtSetArg(args[j], XtNborderWidth, &wbw); j++;
240 XtGetValues(hist->mvw, args, j);
243 XtSetArg(args[j], XtNlongest, &bl); j++;
244 XtSetArg(args[j], XtNinternalWidth, &biw); j++;
245 XtSetArg(args[j], XtNborderWidth, &bbw); j++;
246 XtGetValues(hist->mvb, args, j);
249 nl - 1 - 2*niw - 2*nbw - wl - 2*wiw - 2*wbw - bl - 2*biw - 2*bbw;
250 if (extra < 0) extra = 0;
253 XtSetArg(args[j], XtNwidth, nl + 1 + 2*niw); j++;
254 XtSetValues(hist->mvn, args, j);
257 XtSetArg(args[j], XtNwidth, wl + 2*wiw + extra/2); j++;
258 XtSetValues(hist->mvw, args, j);
261 XtSetArg(args[j], XtNwidth, bl + 2*biw + extra/2); j++;
262 XtSetValues(hist->mvb, args, j);
266 void HistorySet(char movelist[][2*MOVE_LEN],int first,int last,int current){
269 if(last >= hist->aNr) HistoryAlloc(last+_LL_);
270 for(i=0;i<last;i++) {
273 char* p = strchr(movelist[i], ' ');
275 strncpy(hist->white[i/2+1], movelist[i], p-movelist[i]);
276 hist->white[i/2+1][p-movelist[i]] = NULLCHAR;
278 strcpy(hist->white[i/2+1],movelist[i]);
281 strcpy(hist->white[i/2+1],dots);
285 char* p = strchr(movelist[i], ' ');
287 strncpy(hist->black[i/2+1], movelist[i], p-movelist[i]);
288 hist->black[i/2+1][p-movelist[i]] = NULLCHAR;
290 strcpy(hist->black[i/2+1],movelist[i]);
293 strcpy(hist->black[i/2+1],"");
297 strcpy(hist->black[last/2+1],"");
300 XawFormDoLayout(hist->vbox, False);
301 XawListChange(hist->mvn,hist->Nr+b,m,0,True);
302 XawListChange(hist->mvw,hist->white+b,m,0,True);
303 XawListChange(hist->mvb,hist->black+b,m,0,True);
305 XawFormDoLayout(hist->vbox, True);
307 XawListUnhighlight(hist->mvw);
308 XawListUnhighlight(hist->mvb);
310 else if((current%2)==0){
311 XawListHighlight(hist->mvw, current/2+1);
312 XawListUnhighlight(hist->mvb);
315 XawListUnhighlight(hist->mvw);
316 if(current) XawListHighlight(hist->mvb, current/2+1);
317 else XawListUnhighlight(hist->mvb);
322 Widget HistoryCreate()
327 Widget layout,form,b_close;
329 "<Key>Up: BackwardProc() \n \
330 <Key>Left: BackwardProc() \n \
331 <Key>Down: ForwardProc() \n \
332 <Key>Right: ForwardProc() \n";
333 /*--- allocate memory for move-strings ---*/
336 /*-------- create the widgets ---------------*/
338 XtSetArg(args[j], XtNresizable, True); j++;
339 XtSetArg(args[j], XtNallowShellResize, True); j++;
342 XtCreatePopupShell("Move list", topLevelShellWidgetClass,
343 shellWidget, args, j);
346 XtCreatePopupShell("Move list", transientShellWidgetClass,
347 shellWidget, args, j);
350 XtSetArg(args[j], XtNborderWidth, 0); j++;
351 XtSetArg(args[j], XtNdefaultDistance, 0); j++;
353 XtCreateManagedWidget(layoutName, formWidgetClass, hist->sh,
357 XtSetArg(args[j], XtNborderWidth, 0); j++;
358 XtSetArg(args[j], XtNresizable, True); j++;
361 XtCreateManagedWidget("form", formWidgetClass, layout, args, j);
366 XtSetArg(args[j], XtNtop, XtChainTop); j++;
367 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
368 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
369 XtSetArg(args[j], XtNright, XtChainRight); j++;
371 XtSetArg(args[j], XtNborderWidth, 1); j++;
372 XtSetArg(args[j], XtNresizable, False); j++;
373 XtSetArg(args[j], XtNallowVert, True); j++;
374 XtSetArg(args[j], XtNallowHoriz, True); j++;
375 XtSetArg(args[j], XtNforceBars, False); j++;
376 XtSetArg(args[j], XtNheight, 280); j++;
378 XtCreateManagedWidget("viewport", viewportWidgetClass,
381 XtSetArg(args[j], XtNborderWidth, 0); j++;
382 XtSetArg(args[j], XtNorientation,XtorientHorizontal);j++;
384 XtCreateManagedWidget("vbox", formWidgetClass, hist->viewport, args, j);
387 XtSetArg(args[j], XtNtop, XtChainTop); j++;
388 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
389 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
390 XtSetArg(args[j], XtNright, XtChainLeft); j++;
392 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
393 XtSetArg(args[j], XtNforceColumns, True); j++;
394 XtSetArg(args[j], XtNverticalList, True); j++;
395 XtSetArg(args[j], XtNborderWidth, 0); j++;
396 XtSetArg(args[j], XtNresizable,True);j++;
397 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
398 hist->mvn = XtCreateManagedWidget("movesn", listWidgetClass,
399 hist->vbox, args, j);
400 XtAddCallback(hist->mvn, XtNcallback, HistoryMoveProc, (XtPointer) hist);
403 XtSetArg(args[j], XtNtop, XtChainTop); j++;
404 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
405 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
406 XtSetArg(args[j], XtNright, XtRubber); j++;
408 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
409 XtSetArg(args[j], XtNforceColumns, True); j++;
410 XtSetArg(args[j], XtNverticalList, True); j++;
411 XtSetArg(args[j], XtNborderWidth, 0); j++;
412 XtSetArg(args[j], XtNresizable,True);j++;
413 XtSetArg(args[j], XtNfromHoriz, hist->mvn); j++;
414 hist->mvw = XtCreateManagedWidget("movesw", listWidgetClass,
415 hist->vbox, args, j);
416 XtAddCallback(hist->mvw, XtNcallback, HistoryMoveProc, (XtPointer) hist);
419 XtSetArg(args[j], XtNtop, XtChainTop); j++;
420 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
421 XtSetArg(args[j], XtNleft, XtRubber); j++;
422 XtSetArg(args[j], XtNright, XtRubber); j++;
424 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
425 XtSetArg(args[j], XtNforceColumns, True); j++;
426 XtSetArg(args[j], XtNverticalList, True); j++;
427 XtSetArg(args[j], XtNborderWidth, 0); j++;
428 XtSetArg(args[j], XtNresizable,True);j++;
429 XtSetArg(args[j], XtNfromHoriz, hist->mvw); j++;
430 hist->mvb = XtCreateManagedWidget("movesb", listWidgetClass,
431 hist->vbox, args, j);
432 XtAddCallback(hist->mvb, XtNcallback, HistoryMoveProc, (XtPointer) hist);
435 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
436 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
437 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
438 XtSetArg(args[j], XtNright, XtChainLeft); j++;
439 XtSetArg(args[j], XtNfromVert, hist->viewport); j++;
440 b_close= XtCreateManagedWidget("Close", commandWidgetClass,
442 XtAddCallback(b_close, XtNcallback, HistoryPopDown, (XtPointer) 0);
444 XtAugmentTranslations(hist->sh,XtParseTranslationTable (trstr));
446 XtRealizeWidget(hist->sh);
447 CatchDeleteWindow(hist->sh, "HistoryPopDown");
449 for(i=1;i<hist->aNr;i++){
450 strcpy(hist->white[i],dots);
451 strcpy(hist->black[i],"");
454 // [HGM] remember old position
456 XtSetArg(args[j], XtNx, &gameHistoryX); j++;
\r
457 XtSetArg(args[j], XtNy, &gameHistoryY); j++;
\r
458 XtGetValues(hist->sh, args, j);
\r
469 if(!hist) HistoryCreate();
470 XtPopup(hist->sh, XtGrabNone);
472 // [HGM] restore old position
474 XtSetArg(args[j], XtNx, gameHistoryX); j++;
\r
475 XtSetArg(args[j], XtNy, gameHistoryY); j++;
\r
476 XtSetValues(hist->sh, args, j);
\r
479 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
480 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Move History"),
487 HistoryShowProc(w, event, prms, nprms)
496 } else if (hist->Up) {
497 HistoryPopDown(0,0,0);
501 ToNrEvent(currentMove);