4 * Author: Alessandro Scotti (Dec 2005)
5 * Translated to X by H.G.Muller (Nov 2009)
7 * Copyright 2005 Alessandro Scotti
9 * Enhancements Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
11 * ------------------------------------------------------------------------
13 * GNU XBoard is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or (at
16 * your option) any later version.
18 * GNU XBoard is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see http://www.gnu.org/licenses/.
26 * ------------------------------------------------------------------------
27 ** See the file ChangeLog for a revision history. */
34 #include <sys/types.h>
39 #else /* not STDC_HEADERS */
40 extern char *getenv();
43 # else /* not HAVE_STRING_H */
45 # endif /* not HAVE_STRING_H */
46 #endif /* not STDC_HEADERS */
52 #include <X11/Intrinsic.h>
53 #include <X11/StringDefs.h>
54 #include <X11/Shell.h>
55 #include <X11/Xaw/Dialog.h>
56 #include <X11/Xaw/Form.h>
57 #include <X11/Xaw/List.h>
58 #include <X11/Xaw/Label.h>
59 #include <X11/Xaw/SimpleMenu.h>
60 #include <X11/Xaw/SmeBSB.h>
61 #include <X11/Xaw/SmeLine.h>
62 #include <X11/Xaw/Box.h>
63 #include <X11/Xaw/Paned.h>
64 #include <X11/Xaw/MenuButton.h>
65 #include <X11/cursorfont.h>
66 #include <X11/Xaw/Text.h>
67 #include <X11/Xaw/AsciiText.h>
68 #include <X11/Xaw/Viewport.h>
70 #include <cairo/cairo.h>
71 #include <cairo/cairo-xlib.h>
79 #include "evalgraph.h"
80 #include "xevalgraph.h"
84 # define _(s) gettext (s)
85 # define N_(s) gettext_noop (s)
99 Pixmap icons[8]; // [HGM] this front-end array translates back-end icon indicator to handle
100 Widget outputField[2][7]; // [HGM] front-end array to translate output field to window handle
101 static char *title = N_("Evaluation graph");
103 //extern WindowPlacement wpEvalGraph;
105 Position evalGraphX = -1, evalGraphY = -1;
106 Dimension evalGraphW, evalGraphH;
108 /* Module variables */
110 char *crWhite = "#FFFFB0";
111 char *crBlack = "#AD5D3D";
112 static Window eGraphWindow;
113 static cairo_surface_t *cs;
115 static Option *EvalCallback P((int button, int x, int y));
118 ChoosePen(cairo_t *cr, int i)
122 SetPen(cr, 1.0, "#000000", 0);
125 SetPen(cr, 1.0, "#A0A0A0", 1);
128 SetPen(cr, 1.0, "#0000FF", 1);
131 SetPen(cr, 3.0, crWhite, 0);
134 SetPen(cr, 3.0, crBlack, 0);
137 SetPen(cr, 3.0, "#E0E0F0", 0);
142 // [HGM] front-end, added as wrapper to avoid use of LineTo and MoveToEx in other routines (so they can be back-end)
144 DrawSegment (int x, int y, int *lastX, int *lastY, enum PEN penType)
146 static int curX, curY;
148 if(penType != PEN_NONE) {
149 cairo_t *cr = cairo_create(cs);
150 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
151 cairo_move_to (cr, curX, curY);
152 cairo_line_to (cr, x,y);
153 ChoosePen(cr, penType);
158 if(lastX != NULL) { *lastX = curX; *lastY = curY; }
162 // front-end wrapper for drawing functions to do rectangles
164 DrawRectangle (int left, int top, int right, int bottom, int side, int style)
168 cr = cairo_create (cs);
169 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
170 cairo_rectangle (cr, left, top, right-left, bottom-top);
173 case 0: ChoosePen(cr, PEN_BOLDWHITE); break;
174 case 1: ChoosePen(cr, PEN_BOLDBLACK); break;
175 case 2: ChoosePen(cr, PEN_BACKGD); break;
181 cairo_rectangle (cr, left, top, right-left-1, bottom-top-1);
182 ChoosePen(cr, PEN_BLACK);
189 // front-end wrapper for putting text in graph
191 DrawEvalText (char *buf, int cbBuf, int y)
193 // the magic constants 8 and 5 should really be derived from the font size somehow
194 cairo_text_extents_t extents;
195 cairo_t *cr = cairo_create(cs);
197 /* GTK-TODO this has to go into the font-selection */
198 cairo_select_font_face (cr, "Sans",
199 CAIRO_FONT_SLANT_NORMAL,
200 CAIRO_FONT_WEIGHT_NORMAL);
201 cairo_set_font_size (cr, 12.0);
204 cairo_text_extents (cr, buf, &extents);
206 cairo_move_to (cr, MarginX - 2 - 8*cbBuf, y+5);
207 cairo_text_path (cr, buf);
208 cairo_set_source_rgb (cr, 0.0, 0.0, 0);
209 cairo_fill_preserve (cr);
210 cairo_set_source_rgb (cr, 0, 1.0, 0);
211 cairo_set_line_width (cr, 0.1);
218 static int initDone = FALSE;
221 InitializeEvalGraph (Option *opt, int w, int h)
223 eGraphWindow = XtWindow(opt->handle);
227 XtSetArg(args[0], XtNwidth, &evalGraphW);
228 XtSetArg(args[1], XtNheight, &evalGraphH);
229 XtGetValues(opt->handle, args, 2);
230 nWidthPB = evalGraphW; nHeightPB = evalGraphH;
231 } else nWidthPB = w, nHeightPB = h;
233 if(cs) cairo_surface_destroy(cs);
234 cs=cairo_xlib_surface_create(xDisplay, eGraphWindow, DefaultVisual(xDisplay, 0), nWidthPB, nHeightPB);
239 // The following stuff is really back-end (but too little to bother with a separate file)
243 { // back-end painting; calls back front-end primitives for lines, rectangles and text
244 char *t = MakeEvalTitle(_(title));
245 if(t != title && nWidthPB < 340) t = MakeEvalTitle(nWidthPB < 240 ? "" : _("Eval"));
247 SetDialogTitle(EvalGraphDlg, t);
251 EvalClick (int x, int y)
253 int index = GetMoveIndexFromPoint( x, y );
255 if( index >= 0 && index < currLast ) ToNrEvent( index + 1 );
258 static Option graphOptions[] = {
259 { 150, 0x9C, 300, NULL, (void*) &EvalCallback, NULL, NULL, Graph , "" },
260 { 0, 2, 0, NULL, NULL, "", NULL, EndMark , "" }
264 EvalCallback (int button, int x, int y)
266 if(!initDone) return NULL;
269 case 10: // expose event
270 /* Create or recreate paint box if needed */
271 if(x != nWidthPB || y != nHeightPB) {
272 InitializeEvalGraph(&graphOptions[0], x, y);
278 case 1: EvalClick(x, y); // left button
279 default: break; // other buttons ignored
281 return NULL; // no context menu!
287 if (GenericPopUp(graphOptions, _(title), EvalGraphDlg, BoardWindow, NONMODAL, 1)) {
288 InitializeEvalGraph(&graphOptions[0], 0, 0); // first time: add callbacks and initialize pens
290 SetDialogTitle(EvalGraphDlg, _(title));
291 SetIconName(EvalGraphDlg, _(title));
294 MarkMenu("View.EvaluationGraph", EvalGraphDlg);
296 // ShowThinkingEvent(); // [HGM] thinking: might need to prompt engine for thinking output
302 PopDown(EvalGraphDlg);
304 // ShowThinkingEvent(); // [HGM] thinking: might need to shut off thinking output
310 return shellUp[EvalGraphDlg];
314 EvalGraphDialogExists ()
316 return DialogExists(EvalGraphDlg);
322 if (!PopDown(EvalGraphDlg)) EvalGraphPopUp();
325 // This function is the interface to the back-end.
328 EvalGraphSet (int first, int last, int current, ChessProgramStats_Move * pvInfo)
330 /* [AS] Danger! For now we rely on the pvInfo parameter being a static variable! */
334 currCurrent = current;
337 if( DialogExists(EvalGraphDlg) ) {