refactoring evalgraph code
[xboard.git] / winboard / wevalgraph.c
index 21fd1e4..ec57ab3 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Evaluation graph\r
+ * wevalgraph.c - Evaluation graph front-end part\r
  *\r
  * Author: Alessandro Scotti (Dec 2005)\r
  *\r
 \r
 #include "config.h"\r
 \r
-#include <windows.h> /* required for all Windows applications */\r
-//include <richedit.h>\r
+#include <windows.h>\r
+#include <commdlg.h>\r
+#include <dlgs.h>\r
 #include <stdio.h>\r
-//include <stdlib.h>\r
-//include <malloc.h>\r
 \r
 #include "common.h"\r
 #include "frontend.h"\r
 #include "backend.h"\r
-\r
-/* Module globals */ // used to communicate between back-end and front-end part\r
-static ChessProgramStats_Move * currPvInfo;\r
-static int currFirst = 0;\r
-static int currLast = 0;\r
-static int currCurrent = -1;\r
-\r
-static int nWidthPB = 0;\r
-static int nHeightPB = 0;\r
-\r
-static int MarginX = 18;\r
-static int MarginW = 4;\r
-static int MarginH = 4;\r
-\r
-#define MIN_HIST_WIDTH  4\r
-#define MAX_HIST_WIDTH  10\r
-\r
-#define PEN_NONE       0\r
-#define PEN_BLACK      1\r
-#define PEN_DOTTED     2\r
-#define PEN_BLUEDOTTED 3\r
-#define PEN_BOLD       4 /* or 5 for black */\r
-\r
-#define FILLED 1\r
-#define OPEN   0\r
-\r
-// calls from back-end part into front-end\r
-static void DrawSegment( int x, int y, int *lastX, int *lastY, int penType );\r
-void DrawRectangle( int left, int top, int right, int bottom, int side, int style );\r
-void DrawEvalText(char *buf, int cbBuf, int y);\r
-\r
-\r
-// back-end\r
-static void DrawLine( int x1, int y1, int x2, int y2, int penType )\r
-{\r
-    DrawSegment( x1, y1, NULL, NULL, PEN_NONE );\r
-    DrawSegment( x2, y2, NULL, NULL, penType );\r
-}\r
-\r
-// back-end\r
-static void DrawLineEx( int x1, int y1, int x2, int y2, int penType )\r
-{\r
-    int savX, savY;\r
-    DrawSegment( x1, y1, &savX, &savY, PEN_NONE );\r
-    DrawSegment( x2, y2, NULL, NULL, penType );\r
-    DrawSegment( savX, savY, NULL, NULL, PEN_NONE );\r
-}\r
-\r
-// back-end\r
-static int GetPvScore( int index )\r
-{\r
-    int score = currPvInfo[ index ].score;\r
-\r
-    if( index & 1 ) score = -score; /* Flip score for black */\r
-\r
-    return score;\r
-}\r
-\r
-// back-end\r
-/*\r
-    For a centipawn value, this function returns the height of the corresponding\r
-    histogram, centered on the reference axis.\r
-\r
-    Note: height can be negative!\r
-*/\r
-static int GetValueY( int value )\r
-{\r
-    if( value < -700 ) value = -700;\r
-    if( value > +700 ) value = +700;\r
-\r
-    return (nHeightPB / 2) - (int)(value * (nHeightPB - 2*MarginH) / 1400.0);\r
-}\r
-\r
-// the brush selection is made part of the DrawLine, by passing a style argument\r
-// the wrapper for doing the text output makes this back-end\r
-static void DrawAxisSegmentHoriz( int value, BOOL drawValue )\r
-{\r
-    int y = GetValueY( value*100 );\r
-\r
-    if( drawValue ) {\r
-        char buf[MSG_SIZ], *b = buf;\r
-\r
-        if( value > 0 ) *b++ = '+';\r
-       sprintf(b, "%d", value);\r
-\r
-       DrawEvalText(buf, strlen(buf), y);\r
-    }\r
-    // [HGM] counts on DrawEvalText to have select transparent background for dotted line!\r
-    DrawLine( MarginX, y, MarginX + MarginW, y, PEN_BLACK ); // Y-axis tick marks\r
-    DrawLine( MarginX + MarginW, y, nWidthPB - MarginW, y, PEN_DOTTED ); // hor grid\r
-}\r
-\r
-// The DrawLines again must select their own brush.\r
-// the initial brush selection is useless? BkMode needed for dotted line and text\r
-static void DrawAxis()\r
-{\r
-    int cy = nHeightPB / 2;\r
-    \r
-//    SelectObject( hdcPB, GetStockObject(NULL_BRUSH) );\r
-\r
-//    SetBkMode( hdcPB, TRANSPARENT );\r
-\r
-    DrawAxisSegmentHoriz( +5, TRUE );\r
-    DrawAxisSegmentHoriz( +3, FALSE );\r
-    DrawAxisSegmentHoriz( +1, FALSE );\r
-    DrawAxisSegmentHoriz(  0, TRUE );\r
-    DrawAxisSegmentHoriz( -1, FALSE );\r
-    DrawAxisSegmentHoriz( -3, FALSE );\r
-    DrawAxisSegmentHoriz( -5, TRUE );\r
-\r
-    DrawLine( MarginX + MarginW, cy, nWidthPB - MarginW, cy, PEN_BLACK ); // x-axis\r
-    DrawLine( MarginX + MarginW, MarginH, MarginX + MarginW, nHeightPB - MarginH, PEN_BLACK ); // y-axis\r
-}\r
-\r
-// back-end\r
-static void DrawHistogram( int x, int y, int width, int value, int side )\r
-{\r
-    int left, top, right, bottom;\r
-\r
-    if( value > -25 && value < +25 ) return;\r
-\r
-    left = x;\r
-    right = left + width + 1;\r
-\r
-    if( value > 0 ) {\r
-        top = GetValueY( value );\r
-        bottom = y+1;\r
-    }\r
-    else {\r
-        top = y;\r
-        bottom = GetValueY( value ) + 1;\r
-    }\r
-\r
-\r
-    if( width == MIN_HIST_WIDTH ) {\r
-        right--;\r
-        DrawRectangle( left, top, right, bottom, side, FILLED );\r
-    }\r
-    else {\r
-        DrawRectangle( left, top, right, bottom, side, OPEN );\r
-    }\r
-}\r
-\r
-// back-end\r
-static void DrawSeparator( int index, int x )\r
-{\r
-    if( index > 0 ) {\r
-        if( index == currCurrent ) {\r
-            DrawLineEx( x, MarginH, x, nHeightPB - MarginH, PEN_BLUEDOTTED );\r
-        }\r
-        else if( (index % 20) == 0 ) {\r
-            DrawLineEx( x, MarginH, x, nHeightPB - MarginH, PEN_DOTTED );\r
-        }\r
-    }\r
-}\r
-\r
-// made back-end by replacing MoveToEx and LineTo by DrawSegment\r
-/* Actually draw histogram as a diagram, cause there's too much data */\r
-static void DrawHistogramAsDiagram( int cy, int paint_width, int hist_count )\r
-{\r
-    double step;\r
-    int i;\r
-\r
-    /* Rescale the graph every few moves (as opposed to every move) */\r
-    hist_count -= hist_count % 8;\r
-    hist_count += 8;\r
-    hist_count /= 2;\r
-\r
-    step = (double) paint_width / (hist_count + 1);\r
-\r
-    for( i=0; i<2; i++ ) {\r
-        int index = currFirst;\r
-        int side = (currCurrent + i + 1) & 1; /* Draw current side last */\r
-        double x = MarginX + MarginW;\r
-\r
-        if( (index & 1) != side ) {\r
-            x += step / 2;\r
-            index++;\r
-        }\r
-\r
-        DrawSegment( (int) x, cy, NULL, NULL, PEN_NONE );\r
-\r
-        index += 2;\r
-\r
-        while( index < currLast ) {\r
-            x += step;\r
-\r
-            DrawSeparator( index, (int) x );\r
-\r
-            /* Extend line up to current point */\r
-            if( currPvInfo[index].depth > 0 ) {\r
-                DrawSegment((int) x, GetValueY( GetPvScore(index) ), NULL, NULL, PEN_BOLD + side );\r
-            }\r
-\r
-            index += 2;\r
-        }\r
-    }\r
-}\r
-\r
-// back-end, delete pen selection\r
-static void DrawHistogramFull( int cy, int hist_width, int hist_count )\r
-{\r
-    int i;\r
-\r
-//    SelectObject( hdcPB, GetStockObject(BLACK_PEN) );\r
-\r
-    for( i=0; i<hist_count; i++ ) {\r
-        int index = currFirst + i;\r
-        int x = MarginX + MarginW + index * hist_width;\r
-\r
-        /* Draw a separator every 10 moves */\r
-        DrawSeparator( index, x );\r
-\r
-        /* Draw histogram */\r
-        if( currPvInfo[i].depth > 0 ) {\r
-            DrawHistogram( x, cy, hist_width, GetPvScore(index), index & 1 );\r
-        }\r
-    }\r
-}\r
-\r
-typedef struct {\r
-    int cy;\r
-    int hist_width;\r
-    int hist_count;\r
-    int paint_width;\r
-} VisualizationData;\r
-\r
-// back-end\r
-static Boolean InitVisualization( VisualizationData * vd )\r
-{\r
-    BOOL result = FALSE;\r
-\r
-    vd->cy = nHeightPB / 2;\r
-    vd->hist_width = MIN_HIST_WIDTH;\r
-    vd->hist_count = currLast - currFirst;\r
-    vd->paint_width = nWidthPB - MarginX - 2*MarginW;\r
-\r
-    if( vd->hist_count > 0 ) {\r
-        result = TRUE;\r
-\r
-        /* Compute width */\r
-        vd->hist_width = vd->paint_width / vd->hist_count;\r
-\r
-        if( vd->hist_width > MAX_HIST_WIDTH ) vd->hist_width = MAX_HIST_WIDTH;\r
-\r
-        vd->hist_width -= vd->hist_width % 2;\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-// back-end\r
-static void DrawHistograms()\r
-{\r
-    VisualizationData vd;\r
-\r
-    if( InitVisualization( &vd ) ) {\r
-        if( vd.hist_width < MIN_HIST_WIDTH ) {\r
-            DrawHistogramAsDiagram( vd.cy, vd.paint_width, vd.hist_count );\r
-        }\r
-        else {\r
-            DrawHistogramFull( vd.cy, vd.hist_width, vd.hist_count );\r
-        }\r
-    }\r
-}\r
-\r
-// back-end\r
-int GetMoveIndexFromPoint( int x, int y )\r
-{\r
-    int result = -1;\r
-    int start_x = MarginX + MarginW;\r
-    VisualizationData vd;\r
-\r
-    if( x >= start_x && InitVisualization( &vd ) ) {\r
-        /* Almost an hack here... we duplicate some of the paint logic */\r
-        if( vd.hist_width < MIN_HIST_WIDTH ) {\r
-            double step;\r
-\r
-            vd.hist_count -= vd.hist_count % 8;\r
-            vd.hist_count += 8;\r
-            vd.hist_count /= 2;\r
-\r
-            step = (double) vd.paint_width / (vd.hist_count + 1);\r
-            step /= 2;\r
-\r
-            result = (int) (0.5 + (double) (x - start_x) / step);\r
-        }\r
-        else {\r
-            result = (x - start_x) / vd.hist_width;\r
-        }\r
-    }\r
-\r
-    if( result >= currLast ) {\r
-        result = -1;\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-// init and display part split of so they can be moved to front end\r
-void PaintEvalGraph( void )\r
-{\r
-    /* Draw */\r
-    DrawRectangle(0, 0, nWidthPB, nHeightPB, 2, FILLED);\r
-    DrawAxis();\r
-    DrawHistograms();\r
-}\r
-\r
-// ------------------------------------------ front-end starts here ----------------------------------------------\r
-\r
-#include <commdlg.h>\r
-#include <dlgs.h>\r
-\r
 #include "winboard.h"\r
+#include "evalgraph.h"\r
 #include "wsnap.h"\r
 \r
 #define WM_REFRESH_GRAPH    (WM_USER + 1)\r
 \r
-// calls of front-end part into back-end part\r
-extern int GetMoveIndexFromPoint( int x, int y );\r
-extern void PaintEvalGraph( void );\r
-\r
-/* Imports from winboard.c */\r
-static BOOLEAN evalGraphDialogUp; // should be back-end, really\r
-\r
-extern HINSTANCE hInst;\r
-extern HWND hwndMain;\r
-\r
-extern WindowPlacement wpEvalGraph;\r
+/* Module globals */\r
+static BOOLEAN evalGraphDialogUp;\r
 \r
 static COLORREF crWhite = RGB( 0xFF, 0xFF, 0xB0 );\r
 static COLORREF crBlack = RGB( 0xAD, 0x5D, 0x3D );\r
@@ -380,7 +58,7 @@ Boolean EvalGraphIsUp()
 }\r
 \r
 // [HGM] front-end, added as wrapper to avoid use of LineTo and MoveToEx in other routines (so they can be back-end) \r
-static void DrawSegment( int x, int y, int *lastX, int *lastY, int penType )\r
+void DrawSegment( int x, int y, int *lastX, int *lastY, int penType )\r
 {\r
     POINT stPt;\r
     if(penType == PEN_NONE) MoveToEx( hdcPB, x, y, &stPt ); else {\r
@@ -633,4 +311,3 @@ VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pv
         SendMessage( evalGraphDialog, WM_REFRESH_GRAPH, 0, 0 );\r
     }\r
 }\r
-\r