2 * xhistory.c -- Move list window, part of X front end for XBoard
4 * Copyright 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
5 * ------------------------------------------------------------------------
7 * GNU XBoard is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or (at
10 * your option) any later version.
12 * GNU XBoard is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see http://www.gnu.org/licenses/. *
20 *------------------------------------------------------------------------
21 ** See the file ChangeLog for a revision history. */
28 #include <sys/types.h>
33 #else /* not STDC_HEADERS */
34 extern char *getenv();
37 # else /* not HAVE_STRING_H */
39 # endif /* not HAVE_STRING_H */
40 #endif /* not STDC_HEADERS */
46 #include <X11/Intrinsic.h>
47 #include <X11/StringDefs.h>
48 #include <X11/Shell.h>
49 #include <X11/Xaw/Dialog.h>
50 #include <X11/Xaw/Form.h>
51 #include <X11/Xaw/List.h>
52 #include <X11/Xaw/Label.h>
53 #include <X11/Xaw/SimpleMenu.h>
54 #include <X11/Xaw/SmeBSB.h>
55 #include <X11/Xaw/SmeLine.h>
56 #include <X11/Xaw/Box.h>
57 #include <X11/Xaw/Paned.h>
58 #include <X11/Xaw/MenuButton.h>
59 #include <X11/cursorfont.h>
60 #include <X11/Xaw/Text.h>
61 #include <X11/Xaw/AsciiText.h>
62 #include <X11/Xaw/Viewport.h>
70 #include "xevalgraph.h"
73 # define _(s) gettext (s)
74 # define N_(s) gettext_noop (s)
83 String *Nr,*white,*black;
84 int aNr; /* space actually alocated */
85 Widget mvn,mvw,mvb,vbox,viewport,sh;
89 struct History *hist=0;
91 Position gameHistoryX, gameHistoryY;
92 Dimension gameHistoryW, gameHistoryH;
95 HistoryPopDown(w, client_data, call_data)
97 XtPointer client_data, call_data;
103 // [HGM] remember old position
105 XtSetArg(args[j], XtNx, &gameHistoryX); j++;
106 XtSetArg(args[j], XtNy, &gameHistoryY); j++;
107 XtSetArg(args[j], XtNwidth, &gameHistoryW); j++;
108 XtSetArg(args[j], XtNheight, &gameHistoryH); j++;
109 XtGetValues(hist->sh, args, j);
110 wpMoveHistory.x = gameHistoryX - 4;
111 wpMoveHistory.y = gameHistoryY - 23;
112 wpMoveHistory.width = gameHistoryW;
113 wpMoveHistory.height = gameHistoryH;
119 XtSetArg(args[j], XtNleftBitmap, None); j++;
120 XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Move History"),
124 void HistoryMoveProc(Widget w, XtPointer closure, XtPointer call_data)
127 XawListReturnStruct *R = (XawListReturnStruct *) call_data;
128 if (w == hist->mvn || w == hist->mvw) {
129 to=2*R->list_index-1;
132 else if (w == hist->mvb) {
138 void HistoryAlloc(int len){
141 free(hist->Nr[0]);free(hist->white[0]);free(hist->black[0]);
142 free(hist->Nr);free(hist->white);free(hist->black);
145 hist=(struct History*)malloc(sizeof(struct History));
148 hist->Nr=(String*)malloc(hist->aNr*sizeof(String*));
149 hist->white=(String*)malloc(hist->aNr*sizeof(String*));
150 hist->black=(String*)malloc(hist->aNr*sizeof(String*));
152 hist->Nr[0]=(String)malloc(hist->aNr*6);
153 hist->white[0]=(String)malloc(hist->aNr*MOVE_LEN);
154 hist->black[0]=(String)malloc(hist->aNr*MOVE_LEN);
156 sprintf(hist->Nr[0]," ");
157 sprintf(hist->white[0],_("White "));
158 sprintf(hist->black[0],_("Black "));
159 for(i=1;i<hist->aNr;i++){
160 hist->Nr[i]= hist->Nr[i-1]+6;
161 hist->white[i]= hist->white[i-1]+MOVE_LEN;
162 hist->black[i]= hist->black[i-1]+MOVE_LEN;
163 sprintf(hist->Nr[i],"%i.",i);
164 sprintf(hist->white[i],"-----");
165 sprintf(hist->black[i],"-----");
170 /* Find empty space inside vbox form widget and redistribute it amongst
171 the list widgets inside it. */
172 /* This version sort of works */
183 XtSetArg(args[j], XtNx, &x); j++;
184 XtSetArg(args[j], XtNwidth, &w); j++;
185 XtSetArg(args[j], XtNborderWidth, &bw); j++;
186 XtGetValues(hist->mvb, args, j);
190 XtSetArg(args[j], XtNwidth, &w); j++;
191 XtSetArg(args[j], XtNdefaultDistance, &dd); j++;
192 XtGetValues(hist->vbox, args, j);
197 extra = -((-extra)/2);
203 XtSetArg(args[j], XtNwidth, &w); j++;
204 XtGetValues(hist->mvw, args, j);
207 XtSetArg(args[j], XtNwidth, w); j++;
208 XtSetValues(hist->mvw, args, j);
211 XtSetArg(args[j], XtNwidth, &w); j++;
212 XtGetValues(hist->mvb, args, j);
215 XtSetArg(args[j], XtNwidth, w); j++;
216 XtSetValues(hist->mvb, args, j);
219 void HistorySet(char movelist[][2*MOVE_LEN],int first,int last,int current){
223 if(last >= hist->aNr) HistoryAlloc(last+_LL_);
224 for(i=0;i<last;i++) {
227 char* p = strchr(movelist[i], ' ');
229 strncpy(hist->white[i/2+1], movelist[i], p-movelist[i]);
230 hist->white[i/2+1][p-movelist[i]] = NULLCHAR;
232 safeStrCpy(hist->white[i/2+1],movelist[i], MOVE_LEN);
235 safeStrCpy(hist->white[i/2+1],dots, MOVE_LEN);
239 char* p = strchr(movelist[i], ' ');
241 strncpy(hist->black[i/2+1], movelist[i], p-movelist[i]);
242 hist->black[i/2+1][p-movelist[i]] = NULLCHAR;
244 safeStrCpy(hist->black[i/2+1],movelist[i], MOVE_LEN);
247 safeStrCpy(hist->black[i/2+1],"", MOVE_LEN);
251 safeStrCpy(hist->black[last/2+1],"", MOVE_LEN);
254 XawFormDoLayout(hist->vbox, False);
255 XawListChange(hist->mvn,hist->Nr+b,m,0,True);
256 XawListChange(hist->mvw,hist->white+b,m,0,True);
257 XawListChange(hist->mvb,hist->black+b,m,0,True);
259 XawFormDoLayout(hist->vbox, True);
261 XawListUnhighlight(hist->mvw);
262 XawListUnhighlight(hist->mvb);
264 else if((current%2)==0){
265 XawListHighlight(hist->mvw, current/2+1);
266 XawListUnhighlight(hist->mvb);
269 XawListUnhighlight(hist->mvw);
270 if(current) XawListHighlight(hist->mvb, current/2+1);
271 else XawListUnhighlight(hist->mvb);
273 if(scroll = XtNameToWidget(hist->sh, "*form.viewport.vertical")) { // [HGM] always scroll to bottom
274 static char *params[3] = { "", "Forward", "FullLength" };
276 XtCallActionProc(scroll, "StartScroll", &event, params+1, 1);
277 XtCallActionProc(scroll, "NotifyScroll", &event, params+2, 1);
278 XtCallActionProc(scroll, "EndScroll", &event, params, 0);
281 EvalGraphSet( first, last, current, pvInfoList ); // piggy-backed
284 Widget HistoryCreate()
289 Widget layout,form,b_close;
291 "<Key>Up: BackwardProc() \n \
292 <Key>Left: BackwardProc() \n \
293 <Key>Down: ForwardProc() \n \
294 <Key>Right: ForwardProc() \n";
295 /*--- allocate memory for move-strings ---*/
298 /*-------- create the widgets ---------------*/
300 XtSetArg(args[j], XtNresizable, True); j++;
301 XtSetArg(args[j], XtNallowShellResize, True); j++;
303 hist->sh = historyShell =
304 XtCreatePopupShell(_("Move list"), topLevelShellWidgetClass,
305 shellWidget, args, j);
307 hist->sh = historyShell =
308 XtCreatePopupShell(_("Move list"), transientShellWidgetClass,
309 shellWidget, args, j);
312 XtSetArg(args[j], XtNborderWidth, 0); j++;
313 XtSetArg(args[j], XtNdefaultDistance, 0); j++;
315 XtCreateManagedWidget(layoutName, formWidgetClass, hist->sh,
319 XtSetArg(args[j], XtNborderWidth, 0); j++;
320 XtSetArg(args[j], XtNresizable, True); j++;
323 XtCreateManagedWidget("form", formWidgetClass, layout, args, j);
326 XtSetArg(args[j], XtNtop, XtChainTop); j++;
327 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
328 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
329 XtSetArg(args[j], XtNright, XtChainRight); j++;
331 XtSetArg(args[j], XtNborderWidth, 1); j++;
332 XtSetArg(args[j], XtNresizable, False); j++;
333 XtSetArg(args[j], XtNallowVert, True); j++;
334 XtSetArg(args[j], XtNallowHoriz, True); j++;
335 XtSetArg(args[j], XtNforceBars, False); j++;
336 XtSetArg(args[j], XtNheight, 280); j++;
338 XtCreateManagedWidget("viewport", viewportWidgetClass,
341 XtSetArg(args[j], XtNborderWidth, 0); j++;
342 XtSetArg(args[j], XtNorientation,XtorientHorizontal);j++;
344 XtCreateManagedWidget("vbox", formWidgetClass, hist->viewport, args, j);
347 XtSetArg(args[j], XtNtop, XtChainTop); j++;
348 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
349 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
350 XtSetArg(args[j], XtNright, XtChainLeft); j++;
352 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
353 XtSetArg(args[j], XtNforceColumns, True); j++;
354 XtSetArg(args[j], XtNverticalList, True); j++;
355 XtSetArg(args[j], XtNborderWidth, 0); j++;
356 XtSetArg(args[j], XtNresizable,True);j++;
357 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
358 hist->mvn = XtCreateManagedWidget("movesn", listWidgetClass,
359 hist->vbox, args, j);
360 XtAddCallback(hist->mvn, XtNcallback, HistoryMoveProc, (XtPointer) hist);
363 XtSetArg(args[j], XtNtop, XtChainTop); j++;
364 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
365 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
366 XtSetArg(args[j], XtNright, XtRubber); j++;
368 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
369 XtSetArg(args[j], XtNforceColumns, True); j++;
370 XtSetArg(args[j], XtNverticalList, True); j++;
371 XtSetArg(args[j], XtNborderWidth, 0); j++;
372 XtSetArg(args[j], XtNresizable,True);j++;
373 XtSetArg(args[j], XtNfromHoriz, hist->mvn); j++;
374 hist->mvw = XtCreateManagedWidget("movesw", listWidgetClass,
375 hist->vbox, args, j);
376 XtAddCallback(hist->mvw, XtNcallback, HistoryMoveProc, (XtPointer) hist);
379 XtSetArg(args[j], XtNtop, XtChainTop); j++;
380 XtSetArg(args[j], XtNbottom, XtChainTop); j++;
381 XtSetArg(args[j], XtNleft, XtRubber); j++;
382 XtSetArg(args[j], XtNright, XtRubber); j++;
384 XtSetArg(args[j], XtNdefaultColumns, 1); j++;
385 XtSetArg(args[j], XtNforceColumns, True); j++;
386 XtSetArg(args[j], XtNverticalList, True); j++;
387 XtSetArg(args[j], XtNborderWidth, 0); j++;
388 XtSetArg(args[j], XtNresizable,True);j++;
389 XtSetArg(args[j], XtNfromHoriz, hist->mvw); j++;
390 hist->mvb = XtCreateManagedWidget("movesb", listWidgetClass,
391 hist->vbox, args, j);
392 XtAddCallback(hist->mvb, XtNcallback, HistoryMoveProc, (XtPointer) hist);
395 XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
396 XtSetArg(args[j], XtNtop, XtChainBottom); j++;
397 XtSetArg(args[j], XtNleft, XtChainLeft); j++;
398 XtSetArg(args[j], XtNright, XtChainLeft); j++;
399 XtSetArg(args[j], XtNfromVert, hist->viewport); j++;
400 b_close= XtCreateManagedWidget(_("Close"), commandWidgetClass,
402 XtAddCallback(b_close, XtNcallback, HistoryPopDown, (XtPointer) 0);
404 XtAugmentTranslations(hist->sh,XtParseTranslationTable (trstr));
406 XtRealizeWidget(hist->sh);
407 CatchDeleteWindow(hist->sh, "HistoryPopDown");
409 for(i=1;i<hist->aNr;i++){
410 safeStrCpy(hist->white[i],dots, MOVE_LEN);
411 safeStrCpy(hist->black[i],"", MOVE_LEN);
414 if(wpMoveHistory.width > 0) {
415 gameHistoryW = wpMoveHistory.width;
416 gameHistoryH = wpMoveHistory.height;
417 gameHistoryX = wpMoveHistory.x;
418 gameHistoryY = wpMoveHistory.y;
421 // [HGM] restore old position
422 if(gameHistoryW > 0) {
424 XtSetArg(args[j], XtNx, gameHistoryX); j++;
425 XtSetArg(args[j], XtNy, gameHistoryY); j++;
426 XtSetArg(args[j], XtNwidth, gameHistoryW); j++;
427 XtSetArg(args[j], XtNheight, gameHistoryH); j++;
428 XtSetValues(hist->sh, args, j);
430 XtRealizeWidget(hist->sh);
441 if(!hist) HistoryCreate();
443 XtPopup(hist->sh, XtGrabNone);
446 XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
447 XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Move History"),
454 HistoryShowProc(w, event, prms, nprms)
463 } else if (hist->Up) {
464 HistoryPopDown(0,0,0);
468 ToNrEvent(currentMove);
474 return hist && hist->Up;