Control Eval Graph with mouse
authorH.G.Muller <hgm@hgm-xboard.(none)>
Sun, 21 Sep 2014 14:47:41 +0000 (16:47 +0200)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Sun, 28 Sep 2014 20:14:27 +0000 (22:14 +0200)
Let mousewheel control evalZoom, and right-click toggle between
normal view and differential view ('blunder graph').

evalgraph.c
evalgraph.h
nevalgraph.c
winboard/wevalgraph.c

index 2767560..e3608f0 100644 (file)
@@ -53,6 +53,7 @@ int currFirst = 0;
 int currLast = 0;
 int currCurrent = -1;
 int range = 1;
+int differentialView;
 
 int nWidthPB = 0;
 int nHeightPB = 0;
@@ -85,6 +86,7 @@ GetPvScore (int index)
 {
     int score = currPvInfo[ index ].score;
 
+    if(differentialView) score = index < currLast-1 ? -currPvInfo[ index+1 ].score - score : 0;
     if( index & 1 ) score = -score; /* Flip score for black */
 
     return score;
@@ -312,15 +314,26 @@ static void
 DrawHistograms ()
 {
     VisualizationData vd;
+    int i; double step = 1;
 
     if( InitVisualization( &vd ) ) {
         if( vd.hist_width < MIN_HIST_WIDTH ) {
             DrawHistogramAsDiagram( vd.cy, vd.paint_width, vd.hist_count );
+            step = 0.5*vd.paint_width / (((vd.hist_count | 7) + 1)/2 + 1.);
         }
         else {
-            DrawHistogramFull( vd.cy, vd.hist_width, vd.hist_count );
+            DrawHistogramFull( vd.cy, step = vd.hist_width, vd.hist_count );
         }
     }
+    if(!differentialView) return;
+    differentialView = 0;
+    DrawSegment( MarginX + MarginW, vd.cy, NULL, NULL, PEN_NONE );
+    for( i=0; i<vd.hist_count; i++ ) {
+        int index = currFirst + i;
+        int x = MarginX + MarginW + index * step + step/2;
+        DrawSegment((int) x, GetValueY( GetPvScore(index) ), NULL, NULL, PEN_ANY );
+    }
+    differentialView = 1;
 }
 
 // back-end
index 9d3ae7d..6cace1c 100644 (file)
@@ -27,7 +27,7 @@
 #define MIN_HIST_WIDTH  4
 #define MAX_HIST_WIDTH  10
 
-typedef enum { PEN_NONE, PEN_BLACK, PEN_DOTTED, PEN_BLUEDOTTED, PEN_BOLDWHITE, PEN_BOLDBLACK, PEN_BACKGD } PenType;
+typedef enum { PEN_NONE, PEN_BLACK, PEN_DOTTED, PEN_BLUEDOTTED, PEN_BOLDWHITE, PEN_BOLDBLACK, PEN_BACKGD, PEN_ANY } PenType;
 
 #define FILLED 1
 #define OPEN   0
@@ -37,6 +37,7 @@ ChessProgramStats_Move * currPvInfo;
 extern int currFirst;
 extern int currLast;
 extern int currCurrent;
+extern int differentialView;
 
 extern int nWidthPB;
 extern int nHeightPB;
index d904806..0810851 100644 (file)
@@ -65,7 +65,7 @@ extern char *getenv();
 # define N_(s)  s
 #endif
 
-static char *title = N_("Evaluation graph");
+static char *title[2] = { N_("Evaluation graph"), N_("Blunder graph") };
 Option *disp;
 
 /* Module variables */
@@ -100,9 +100,10 @@ static Option graphOptions[] = {
 static void
 DisplayEvalGraph ()
 {   // back-end painting; calls back front-end primitives for lines, rectangles and text
-    char *t = MakeEvalTitle(_(title));
+    char *t = MakeEvalTitle(_(title[differentialView]));
     nWidthPB = disp->max; nHeightPB = disp->value;
-    if(t != title && nWidthPB < 340) t = MakeEvalTitle(nWidthPB < 240 ? "" : _("Eval"));
+    if(t != title[differentialView] && nWidthPB < 340)
+       t = MakeEvalTitle(nWidthPB < 240 ? "" : differentialView ? _("Blunder") : _("Eval"));
     PaintEvalGraph();
     GraphExpose(graphOptions, 0, 0, nWidthPB, nHeightPB);
     SetDialogTitle(EvalGraphDlg, t);
@@ -111,9 +112,13 @@ DisplayEvalGraph ()
 static Option *
 EvalCallback (int button, int x, int y)
 {
+    int dir = appData.zoom + 1;
     if(!initDone) return NULL;
 
     switch(button) {
+       case 3: dir = 0; differentialView = !differentialView;
+       case 4: dir -= 2;
+       case 5: if(dir > 0) appData.zoom = dir;
        case 10: // expose event
            /* Create or recreate paint box if needed */
            if(x != nWidthPB || y != nHeightPB) {
@@ -132,12 +137,12 @@ EvalCallback (int button, int x, int y)
 void
 EvalGraphPopUp ()
 {
-    if (GenericPopUp(graphOptions, _(title), EvalGraphDlg, BoardWindow, NONMODAL, appData.topLevel)) {
+    if (GenericPopUp(graphOptions, _(title[differentialView]), EvalGraphDlg, BoardWindow, NONMODAL, appData.topLevel)) {
        InitializeEvalGraph(&graphOptions[0], wpEvalGraph.width, wpEvalGraph.height); // first time: add callbacks and initialize pens
        disp = graphOptions;
     } else {
-       SetDialogTitle(EvalGraphDlg, _(title));
-       SetIconName(EvalGraphDlg, _(title));
+       SetDialogTitle(EvalGraphDlg, _(title[differentialView]));
+       SetIconName(EvalGraphDlg, _(title[differentialView]));
     }
 
     MarkMenu("View.EvaluationGraph", EvalGraphDlg);
index ee71b60..ca04343 100644 (file)
@@ -51,7 +51,7 @@ static COLORREF crBlack = RGB( 0xAD, 0x5D, 0x3D );
 \r
 static HDC hdcPB = NULL;\r
 static HBITMAP hbmPB = NULL;\r
-static HPEN pens[6]; // [HGM] put all pens in one array\r
+static HPEN pens[PEN_ANY+1]; // [HGM] put all pens in one array\r
 static HBRUSH hbrHist[3] = { NULL, NULL, NULL };\r
 \r
 Boolean EvalGraphIsUp()\r
@@ -156,7 +156,7 @@ static VOID DisplayEvalGraph( HWND hWnd, HDC hDC )
 \r
     // back-end painting; calls back front-end primitives for lines, rectangles and text\r
     PaintEvalGraph();\r
-    SetWindowText(hWnd, MakeEvalTitle(T_("Evaluation Graph")));\r
+    SetWindowText(hWnd, MakeEvalTitle(differentialView ? T_("Blunder Graph") : T_("Evaluation Graph")));\r
 \r
     /* Copy bitmap into destination DC */\r
     BitBlt( hDC, 0, 0, nWidthPB, nHeightPB, hdcPB, 0, 0, SRCCOPY );\r
@@ -208,7 +208,14 @@ LRESULT CALLBACK EvalGraphProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM l
         EndPaint( hDlg, &stPS );\r
         break;\r
 \r
+    case WM_MOUSEWHEEL:\r
+        if((short)HIWORD(wParam) < 0) appData.zoom++;\r
+        if((short)HIWORD(wParam) > 0 && appData.zoom > 1)  appData.zoom--;\r
+        goto paint;\r
+    case WM_RBUTTONDOWN:\r
+        differentialView = !differentialView;\r
     case WM_REFRESH_GRAPH:\r
+    paint:\r
         hDC = GetDC( hDlg );\r
         DisplayEvalGraph( hDlg, hDC );\r
         ReleaseDC( hDlg, hDC );\r