2 * xhistory.c -- Move list window, part of X front end for XBoard
\r
5 * Copyright 2000 Free Software Foundation, Inc.
\r
7 * The following terms apply to the enhanced version of XBoard distributed
\r
8 * by the Free Software Foundation:
\r
9 * ------------------------------------------------------------------------
\r
10 * This program is free software; you can redistribute it and/or modify
\r
11 * it under the terms of the GNU General Public License as published by
\r
12 * the Free Software Foundation; either version 2 of the License, or
\r
13 * (at your option) any later version.
\r
15 * This program is distributed in the hope that it will be useful,
\r
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
18 * GNU General Public License for more details.
\r
20 * You should have received a copy of the GNU General Public License
\r
21 * along with this program; if not, write to the Free Software
\r
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
23 * ------------------------------------------------------------------------
\r
25 * See the file ChangeLog for a revision history.
\r
33 #include <sys/types.h>
\r
36 # include <stdlib.h>
\r
37 # include <string.h>
\r
38 #else /* not STDC_HEADERS */
\r
39 extern char *getenv();
\r
41 # include <string.h>
\r
42 # else /* not HAVE_STRING_H */
\r
43 # include <strings.h>
\r
44 # endif /* not HAVE_STRING_H */
\r
45 #endif /* not STDC_HEADERS */
\r
48 # include <unistd.h>
\r
51 #include <X11/Intrinsic.h>
\r
52 #include <X11/StringDefs.h>
\r
53 #include <X11/Shell.h>
\r
54 #include <X11/Xaw/Dialog.h>
\r
55 #include <X11/Xaw/Form.h>
\r
56 #include <X11/Xaw/List.h>
\r
57 #include <X11/Xaw/Label.h>
\r
58 #include <X11/Xaw/SimpleMenu.h>
\r
59 #include <X11/Xaw/SmeBSB.h>
\r
60 #include <X11/Xaw/SmeLine.h>
\r
61 #include <X11/Xaw/Box.h>
\r
62 #include <X11/Xaw/Paned.h>
\r
63 #include <X11/Xaw/MenuButton.h>
\r
64 #include <X11/cursorfont.h>
\r
65 #include <X11/Xaw/Text.h>
\r
66 #include <X11/Xaw/AsciiText.h>
\r
67 #include <X11/Xaw/Viewport.h>
\r
70 #include "frontend.h"
\r
71 #include "backend.h"
\r
73 #include "xhistory.h"
\r
74 #include "gettext.h"
\r
77 # define _(s) gettext (s)
\r
78 # define N_(s) gettext_noop (s)
\r
86 extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
\r
87 extern Display *xDisplay;
\r
88 extern int squareSize;
\r
89 extern Pixmap xMarkPixmap;
\r
90 extern char *layoutName;
\r
93 String *Nr,*white,*black;
\r
94 int aNr; /* space actually alocated */
\r
95 Widget mvn,mvw,mvb,vbox,viewport,sh;
\r
99 struct History *hist=0;
\r
100 String dots=" ... ";
\r
101 Position gameHistoryX, gameHistoryY;
\r
104 HistoryPopDown(w, client_data, call_data)
\r
106 XtPointer client_data, call_data;
\r
111 // [HGM] remember old position
\r
113 XtSetArg(args[j], XtNx, &gameHistoryX); j++;
\r
114 XtSetArg(args[j], XtNy, &gameHistoryY); j++;
\r
115 XtGetValues(hist->sh, args, j);
\r
117 XtPopdown(hist->sh);
\r
121 XtSetArg(args[j], XtNleftBitmap, None); j++;
\r
122 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Move List"),
\r
126 void HistoryMoveProc(Widget w, XtPointer closure, XtPointer call_data)
\r
129 XawListReturnStruct *R = (XawListReturnStruct *) call_data;
\r
130 if (w == hist->mvn || w == hist->mvw) {
\r
131 to=2*R->list_index-1;
\r
134 else if (w == hist->mvb) {
\r
135 to=2*R->list_index;
\r
140 void HistoryAlloc(int len){
\r
143 free(hist->Nr[0]);free(hist->white[0]);free(hist->black[0]);
\r
144 free(hist->Nr);free(hist->white);free(hist->black);
\r
147 hist=(struct History*)malloc(sizeof(struct History));
\r
150 hist->Nr=(String*)malloc(hist->aNr*sizeof(String*));
\r
151 hist->white=(String*)malloc(hist->aNr*sizeof(String*));
\r
152 hist->black=(String*)malloc(hist->aNr*sizeof(String*));
\r
154 hist->Nr[0]=(String)malloc(hist->aNr*6);
\r
155 hist->white[0]=(String)malloc(hist->aNr*MOVE_LEN);
\r
156 hist->black[0]=(String)malloc(hist->aNr*MOVE_LEN);
\r
158 sprintf(hist->Nr[0]," ");
\r
159 sprintf(hist->white[0],_("White "));
\r
160 sprintf(hist->black[0],_("Black "));
\r
161 for(i=1;i<hist->aNr;i++){
\r
162 hist->Nr[i]= hist->Nr[i-1]+6;
\r
163 hist->white[i]= hist->white[i-1]+MOVE_LEN;
\r
164 hist->black[i]= hist->black[i-1]+MOVE_LEN;
\r
165 sprintf(hist->Nr[i],"%i.",i);
\r
166 sprintf(hist->white[i],"-----");
\r
167 sprintf(hist->black[i],"-----");
\r
173 /* Find empty space inside vbox form widget and redistribute it amongst
\r
174 the list widgets inside it. */
\r
175 /* This version sort of works */
\r
181 Position x, x1, x2;
\r
186 XtSetArg(args[j], XtNx, &x); j++;
\r
187 XtSetArg(args[j], XtNwidth, &w); j++;
\r
188 XtSetArg(args[j], XtNborderWidth, &bw); j++;
\r
189 XtGetValues(hist->mvb, args, j);
\r
193 XtSetArg(args[j], XtNwidth, &w); j++;
\r
194 XtSetArg(args[j], XtNdefaultDistance, &dd); j++;
\r
195 XtGetValues(hist->vbox, args, j);
\r
200 extra = -((-extra)/2);
\r
206 XtSetArg(args[j], XtNwidth, &w); j++;
\r
207 XtGetValues(hist->mvw, args, j);
\r
210 XtSetArg(args[j], XtNwidth, w); j++;
\r
211 XtSetValues(hist->mvw, args, j);
\r
214 XtSetArg(args[j], XtNwidth, &w); j++;
\r
215 XtGetValues(hist->mvb, args, j);
\r
218 XtSetArg(args[j], XtNwidth, w); j++;
\r
219 XtSetValues(hist->mvb, args, j);
\r
222 /* Find empty space inside vbox form widget and redistribute it amongst
\r
223 the list widgets inside it. */
\r
224 /* This version doesn't work */
\r
229 Dimension fw, niw, wiw, biw, nbw, wbw, bbw;
\r
230 int j, nl, wl, bl, fdd;
\r
234 XtSetArg(args[j], XtNwidth, &fw); j++;
\r
235 XtSetArg(args[j], XtNdefaultDistance, &fdd); j++;
\r
236 XtGetValues(hist->vbox, args, j);
\r
239 XtSetArg(args[j], XtNlongest, &nl); j++;
\r
240 XtSetArg(args[j], XtNinternalWidth, &niw); j++;
\r
241 XtSetArg(args[j], XtNborderWidth, &nbw); j++;
\r
242 XtGetValues(hist->mvn, args, j);
\r
245 XtSetArg(args[j], XtNlongest, &wl); j++;
\r
246 XtSetArg(args[j], XtNinternalWidth, &wiw); j++;
\r
247 XtSetArg(args[j], XtNborderWidth, &wbw); j++;
\r
248 XtGetValues(hist->mvw, args, j);
\r
251 XtSetArg(args[j], XtNlongest, &bl); j++;
\r
252 XtSetArg(args[j], XtNinternalWidth, &biw); j++;
\r
253 XtSetArg(args[j], XtNborderWidth, &bbw); j++;
\r
254 XtGetValues(hist->mvb, args, j);
\r
256 extra = fw - 4*fdd -
\r
257 nl - 1 - 2*niw - 2*nbw - wl - 2*wiw - 2*wbw - bl - 2*biw - 2*bbw;
\r
258 if (extra < 0) extra = 0;
\r
261 XtSetArg(args[j], XtNwidth, nl + 1 + 2*niw); j++;
\r
262 XtSetValues(hist->mvn, args, j);
\r
265 XtSetArg(args[j], XtNwidth, wl + 2*wiw + extra/2); j++;
\r
266 XtSetValues(hist->mvw, args, j);
\r
269 XtSetArg(args[j], XtNwidth, bl + 2*biw + extra/2); j++;
\r
270 XtSetValues(hist->mvb, args, j);
\r
274 void HistorySet(char movelist[][2*MOVE_LEN],int first,int last,int current){
\r
277 if(last >= hist->aNr) HistoryAlloc(last+_LL_);
\r
278 for(i=0;i<last;i++) {
\r
280 if(movelist[i][0]) {
\r
281 char* p = strchr(movelist[i], ' ');
\r
283 strncpy(hist->white[i/2+1], movelist[i], p-movelist[i]);
\r
284 hist->white[i/2+1][p-movelist[i]] = NULLCHAR;
\r
286 strcpy(hist->white[i/2+1],movelist[i]);
\r
289 strcpy(hist->white[i/2+1],dots);
\r
292 if(movelist[i][0]) {
\r
293 char* p = strchr(movelist[i], ' ');
\r
295 strncpy(hist->black[i/2+1], movelist[i], p-movelist[i]);
\r
296 hist->black[i/2+1][p-movelist[i]] = NULLCHAR;
\r
298 strcpy(hist->black[i/2+1],movelist[i]);
\r
301 strcpy(hist->black[i/2+1],"");
\r
305 strcpy(hist->black[last/2+1],"");
\r
308 XawFormDoLayout(hist->vbox, False);
\r
309 XawListChange(hist->mvn,hist->Nr+b,m,0,True);
\r
310 XawListChange(hist->mvw,hist->white+b,m,0,True);
\r
311 XawListChange(hist->mvb,hist->black+b,m,0,True);
\r
313 XawFormDoLayout(hist->vbox, True);
\r
315 XawListUnhighlight(hist->mvw);
\r
316 XawListUnhighlight(hist->mvb);
\r
318 else if((current%2)==0){
\r
319 XawListHighlight(hist->mvw, current/2+1);
\r
320 XawListUnhighlight(hist->mvb);
\r
323 XawListUnhighlight(hist->mvw);
\r
324 if(current) XawListHighlight(hist->mvb, current/2+1);
\r
325 else XawListUnhighlight(hist->mvb);
\r
330 Widget HistoryCreate()
\r
335 Widget layout,form,b_close;
\r
337 "<Key>Up: BackwardProc() \n \
\r
338 <Key>Left: BackwardProc() \n \
\r
339 <Key>Down: ForwardProc() \n \
\r
340 <Key>Right: ForwardProc() \n";
\r
341 /*--- allocate memory for move-strings ---*/
\r
342 HistoryAlloc(_LL_);
\r
344 /*-------- create the widgets ---------------*/
\r
346 XtSetArg(args[j], XtNresizable, True); j++;
\r
347 XtSetArg(args[j], XtNallowShellResize, True); j++;
\r
350 XtCreatePopupShell(_("Move list"), topLevelShellWidgetClass,
\r
351 shellWidget, args, j);
\r
354 XtCreatePopupShell(_("Move list"), transientShellWidgetClass,
\r
355 shellWidget, args, j);
\r
358 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
359 XtSetArg(args[j], XtNdefaultDistance, 0); j++;
\r
361 XtCreateManagedWidget(layoutName, formWidgetClass, hist->sh,
\r
365 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
366 XtSetArg(args[j], XtNresizable, True); j++;
\r
369 XtCreateManagedWidget("form", formWidgetClass, layout, args, j);
\r
374 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
375 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
376 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
377 XtSetArg(args[j], XtNright, XtChainRight); j++;
\r
379 XtSetArg(args[j], XtNborderWidth, 1); j++;
\r
380 XtSetArg(args[j], XtNresizable, False); j++;
\r
381 XtSetArg(args[j], XtNallowVert, True); j++;
\r
382 XtSetArg(args[j], XtNallowHoriz, True); j++;
\r
383 XtSetArg(args[j], XtNforceBars, False); j++;
\r
384 XtSetArg(args[j], XtNheight, 280); j++;
\r
386 XtCreateManagedWidget("viewport", viewportWidgetClass,
\r
389 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
390 XtSetArg(args[j], XtNorientation,XtorientHorizontal);j++;
\r
392 XtCreateManagedWidget("vbox", formWidgetClass, hist->viewport, args, j);
\r
395 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
396 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
\r
397 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
398 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
400 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
\r
401 XtSetArg(args[j], XtNforceColumns, True); j++;
\r
402 XtSetArg(args[j], XtNverticalList, True); j++;
\r
403 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
404 XtSetArg(args[j], XtNresizable,True);j++;
\r
405 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
406 hist->mvn = XtCreateManagedWidget("movesn", listWidgetClass,
\r
407 hist->vbox, args, j);
\r
408 XtAddCallback(hist->mvn, XtNcallback, HistoryMoveProc, (XtPointer) hist);
\r
411 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
412 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
\r
413 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
414 XtSetArg(args[j], XtNright, XtRubber); j++;
\r
416 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
\r
417 XtSetArg(args[j], XtNforceColumns, True); j++;
\r
418 XtSetArg(args[j], XtNverticalList, True); j++;
\r
419 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
420 XtSetArg(args[j], XtNresizable,True);j++;
\r
421 XtSetArg(args[j], XtNfromHoriz, hist->mvn); j++;
\r
422 hist->mvw = XtCreateManagedWidget("movesw", listWidgetClass,
\r
423 hist->vbox, args, j);
\r
424 XtAddCallback(hist->mvw, XtNcallback, HistoryMoveProc, (XtPointer) hist);
\r
427 XtSetArg(args[j], XtNtop, XtChainTop); j++;
\r
428 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
\r
429 XtSetArg(args[j], XtNleft, XtRubber); j++;
\r
430 XtSetArg(args[j], XtNright, XtRubber); j++;
\r
432 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
\r
433 XtSetArg(args[j], XtNforceColumns, True); j++;
\r
434 XtSetArg(args[j], XtNverticalList, True); j++;
\r
435 XtSetArg(args[j], XtNborderWidth, 0); j++;
\r
436 XtSetArg(args[j], XtNresizable,True);j++;
\r
437 XtSetArg(args[j], XtNfromHoriz, hist->mvw); j++;
\r
438 hist->mvb = XtCreateManagedWidget("movesb", listWidgetClass,
\r
439 hist->vbox, args, j);
\r
440 XtAddCallback(hist->mvb, XtNcallback, HistoryMoveProc, (XtPointer) hist);
\r
443 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
\r
444 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
\r
445 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
\r
446 XtSetArg(args[j], XtNright, XtChainLeft); j++;
\r
447 XtSetArg(args[j], XtNfromVert, hist->viewport); j++;
\r
448 b_close= XtCreateManagedWidget(_("Close"), commandWidgetClass,
\r
450 XtAddCallback(b_close, XtNcallback, HistoryPopDown, (XtPointer) 0);
\r
452 XtAugmentTranslations(hist->sh,XtParseTranslationTable (trstr));
\r
454 XtRealizeWidget(hist->sh);
\r
455 CatchDeleteWindow(hist->sh, "HistoryPopDown");
\r
457 for(i=1;i<hist->aNr;i++){
\r
458 strcpy(hist->white[i],dots);
\r
459 strcpy(hist->black[i],"");
\r
471 if(!hist) HistoryCreate();
\r
472 XtPopup(hist->sh, XtGrabNone);
\r
474 // [HGM] restore old position
\r
476 XtSetArg(args[j], XtNx, gameHistoryX); j++;
\r
477 XtSetArg(args[j], XtNy, gameHistoryY); j++;
\r
478 XtSetValues(hist->sh, args, j);
\r
481 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
\r
482 XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Move List"),
\r
489 HistoryShowProc(w, event, prms, nprms)
\r
498 } else if (hist->Up) {
\r
499 HistoryPopDown(0,0,0);
\r
503 ToNrEvent(currentMove);
\r