* Massachusetts. \r
*\r
* Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,\r
- * 2007, 2008, 2009 Free Software Foundation, Inc.\r
+ * 2007, 2008, 2009, 2010 Free Software Foundation, Inc.\r
*\r
* Enhancements Copyright 2005 Alessandro Scotti\r
*\r
void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames);\r
void DisplayMove P((int moveNumber));\r
Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen));\r
-void ChatPopUp P(());\r
+void ChatPopUp P((char *s));\r
typedef struct {\r
ChessSquare piece; \r
POINT pos; /* window coordinates of current pos */\r
char *settingsFileName;\r
Boolean saveSettingsOnExit;\r
char installDir[MSG_SIZ];\r
+int errorExitStatus;\r
\r
BoardSize boardSize;\r
Boolean chessProgram;\r
//static int boardX, boardY;\r
int minX, minY; // [HGM] placement: volatile limits on upper-left corner\r
-static int squareSize, lineGap, minorSize;\r
+int squareSize, lineGap, minorSize;\r
static int winW, winH;\r
static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo\r
static int logoHeight = 0;\r
static HBRUSH lightSquareBrush, darkSquareBrush,\r
blackSquareBrush, /* [HGM] for band between board and holdings */\r
explodeBrush, /* [HGM] atomic */\r
+ markerBrush, /* [HGM] markers */\r
whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/;\r
static POINT gridEndpoints[(BOARD_RANKS + BOARD_FILES + 2) * 2];\r
static DWORD gridVertexCounts[BOARD_RANKS + BOARD_FILES + 2];\r
#define ICS_TEXT_MENU_SIZE (IDM_CommandXLast - IDM_CommandX + 1)\r
#define XBOARD FALSE\r
\r
+#define OPTCHAR "/"\r
+#define SEPCHAR "="\r
+\r
#include "args.h"\r
\r
// front-end part of option handling\r
blackPieceBrush = CreateSolidBrush(blackPieceColor);\r
iconBkgndBrush = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));\r
explodeBrush = CreateSolidBrush(highlightSquareColor); // [HGM] atomic\r
+ markerBrush = CreateSolidBrush(premoveHighlightColor); // [HGM] markers\r
/* [AS] Force rendering of the font-based pieces */\r
if( fontBitmapSquareSize > 0 ) {\r
fontBitmapSquareSize = 0;\r
blackRect.right = blackRect.left + boardWidth/2 - 1;\r
blackRect.top = whiteRect.top;\r
blackRect.bottom = whiteRect.bottom;\r
+\r
+ logoHeight = 0; // [HGM] logo: suppress logo after change to tiny layout!\r
}\r
\r
messageRect.left = OUTER_MARGIN + MESSAGE_LINE_LEFTMARGIN;\r
DeleteDC(tmphdc);\r
}\r
\r
+static HDC hdcSeek;\r
+\r
+// [HGM] seekgraph\r
+void DrawSeekAxis( int x, int y, int xTo, int yTo )\r
+{\r
+ POINT stPt;\r
+ HPEN hp = SelectObject( hdcSeek, gridPen );\r
+ MoveToEx( hdcSeek, boardRect.left+x, boardRect.top+y, &stPt );\r
+ LineTo( hdcSeek, boardRect.left+xTo, boardRect.top+yTo );\r
+ SelectObject( hdcSeek, hp );\r
+}\r
+\r
+// front-end wrapper for drawing functions to do rectangles\r
+void DrawSeekBackground( int left, int top, int right, int bottom )\r
+{\r
+ HPEN hp;\r
+ RECT rc;\r
+\r
+ if (hdcSeek == NULL) {\r
+ hdcSeek = GetDC(hwndMain);\r
+ if (!appData.monoMode) {\r
+ SelectPalette(hdcSeek, hPal, FALSE);\r
+ RealizePalette(hdcSeek);\r
+ }\r
+ }\r
+ hp = SelectObject( hdcSeek, gridPen );\r
+ rc.top = boardRect.top+top; rc.left = boardRect.left+left; \r
+ rc.bottom = boardRect.top+bottom; rc.right = boardRect.left+right;\r
+ FillRect( hdcSeek, &rc, lightSquareBrush );\r
+ SelectObject( hdcSeek, hp );\r
+}\r
+\r
+// front-end wrapper for putting text in graph\r
+void DrawSeekText(char *buf, int x, int y)\r
+{\r
+ SIZE stSize;\r
+ SetBkMode( hdcSeek, TRANSPARENT );\r
+ GetTextExtentPoint32( hdcSeek, buf, strlen(buf), &stSize );\r
+ TextOut( hdcSeek, boardRect.left+x-3, boardRect.top+y-stSize.cy/2, buf, strlen(buf) );\r
+}\r
+\r
+void DrawSeekDot(int x, int y, int color)\r
+{\r
+ int square = color & 0x80;\r
+ color &= 0x7F;\r
+ HBRUSH oldBrush = SelectObject(hdcSeek, \r
+ color == 0 ? markerBrush : color == 1 ? darkSquareBrush : explodeBrush);\r
+ if(square)\r
+ Rectangle(hdcSeek, boardRect.left+x - squareSize/9, boardRect.top+y - squareSize/9,\r
+ boardRect.left+x + squareSize/9, boardRect.top+y + squareSize/9);\r
+ else\r
+ Ellipse(hdcSeek, boardRect.left+x - squareSize/8, boardRect.top+y - squareSize/8,\r
+ boardRect.left+x + squareSize/8, boardRect.top+y + squareSize/8);\r
+ SelectObject(hdcSeek, oldBrush);\r
+}\r
+\r
VOID\r
HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)\r
{\r
*/\r
Boolean fullrepaint = repaint;\r
\r
+ if(DrawSeekGraph()) return; // [HG} seekgraph: suppress printing board if seek graph up\r
+\r
if( DrawPositionNeedsFullRepaint() ) {\r
fullrepaint = TRUE;\r
}\r
DrawHighlightsOnDC(hdcmem);\r
DrawBoardOnDC(hdcmem, board, tmphdc);\r
}\r
+ for (row = 0; row < BOARD_HEIGHT; row++) {\r
+ for (column = 0; column < BOARD_WIDTH; column++) {\r
+ if (marker[row][column]) { // marker changes only occur with full repaint!\r
+ HBRUSH oldBrush = SelectObject(hdcmem, \r
+ marker[row][column] == 2 ? markerBrush : explodeBrush);\r
+ SquareToPos(row, column, &x, &y);\r
+ Ellipse(hdcmem, x + squareSize/4, y + squareSize/4,\r
+ x + 3*squareSize/4, y + 3*squareSize/4);\r
+ SelectObject(hdcmem, oldBrush);\r
+ }\r
+ }\r
+ }\r
if(logoHeight) {\r
HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo;\r
if(appData.autoLogo) {\r
VOID\r
MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
{\r
- int x, y;\r
+ int x, y, menuNr;\r
POINT pt;\r
static int recursive = 0;\r
HMENU hmenu;\r
break;\r
\r
case WM_MOUSEMOVE:\r
+ if(SeekGraphClick(Press, pt.x - boardRect.left, pt.y - boardRect.top, 1)) break;\r
+ MovePV(pt.x - boardRect.left, pt.y - boardRect.top, boardRect.bottom - boardRect.top);\r
if ((appData.animateDragging || appData.highlightDragging)\r
&& (wParam & MK_LBUTTON)\r
&& dragInfo.from.x >= 0) \r
}\r
break;\r
\r
+ case WM_MBUTTONUP:\r
+ case WM_RBUTTONUP:\r
+ ReleaseCapture();\r
+ RightClick(Release, pt.x - boardRect.left, pt.y - boardRect.top, &fromX, &fromY);\r
+ break;\r
+ \r
case WM_MBUTTONDOWN:\r
case WM_RBUTTONDOWN:\r
ErrorPopDown();\r
}\r
DrawPosition(TRUE, NULL);\r
\r
- switch (gameMode) {\r
- case EditPosition:\r
- case IcsExamining:\r
- if (x < 0 || y < 0) break;\r
- fromX = x;\r
- fromY = y;\r
+ menuNr = RightClick(Press, pt.x - boardRect.left, pt.y - boardRect.top, &fromX, &fromY);\r
+ switch (menuNr) {\r
+ case 0:\r
if (message == WM_MBUTTONDOWN) {\r
buttonCount = 3; /* even if system didn't think so */\r
if (wParam & MK_SHIFT) \r
MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1);\r
}\r
break;\r
- case IcsPlayingWhite:\r
- case IcsPlayingBlack:\r
- case EditGame:\r
- case MachinePlaysWhite:\r
- case MachinePlaysBlack:\r
- if (appData.testLegality &&\r
- gameInfo.variant != VariantBughouse &&\r
- gameInfo.variant != VariantCrazyhouse) break;\r
- if (x < 0 || y < 0) break;\r
- fromX = x;\r
- fromY = y;\r
+ case 2:\r
+ SetCapture(hwndMain);
+ break;\r
+ case 1:\r
hmenu = LoadMenu(hInst, "DropPieceMenu");\r
SetupDropMenu(hmenu);\r
MenuPopup(hwnd, pt, hmenu, -1);\r
- break;\r
default:\r
break;\r
}\r
break;\r
\r
case IDM_NewChat:\r
- ChatPopUp();\r
+ ChatPopUp(NULL);\r
break;\r
\r
case IDM_CopyPosition:\r
StopExaminingEvent();\r
break;\r
\r
+ case IDM_Upload:\r
+ UploadGameEvent();\r
+ break;\r
+\r
case IDM_TypeInMove:\r
PopUpMoveDialog('\000');\r
break;\r
if (errorDialog == NULL) return;\r
DestroyWindow(errorDialog);\r
errorDialog = NULL;\r
+ if(errorExitStatus) ExitEvent(errorExitStatus);\r
}\r
\r
LRESULT CALLBACK\r
while (e->item) {\r
if (strcmp(e->item, "-") == 0) {\r
AppendMenu(h, MF_SEPARATOR, 0, 0);\r
- } else {\r
+ } else { // [HGM] re-written a bit to use only one AppendMenu call for both cases (| or no |)\r
+ int flags = MF_STRING, j = 0;\r
if (e->item[0] == '|') {\r
- AppendMenu(h, MF_STRING|MF_MENUBARBREAK,\r
- IDM_CommandX + i, &e->item[1]);\r
- } else {\r
- AppendMenu(h, MF_STRING, IDM_CommandX + i, e->item);\r
+ flags |= MF_MENUBARBREAK;\r
+ j++;\r
}\r
+ if(!strcmp(e->command, "none")) flags |= MF_GRAYED; // [HGM] chatclick: provide inactive dummy\r
+ AppendMenu(h, flags, IDM_CommandX + i, e->item + j);\r
}\r
e++;\r
i++;\r
SetWindowText(hInput, buf);\r
SendMessage(hInput, WM_CHAR, '\r', 0);\r
} else {\r
+ if(!strcmp(command, "chat")) { ChatPopUp(name); return; }\r
sprintf(buf, "%s %s ", command, name); /* trailing space */\r
SetWindowText(hInput, buf);\r
sel.cpMin = 999999;\r
}\r
return 0;\r
} // [HGM] navigate: for Ctrl+R, flow into nex case (moved up here) to summon up menu\r
- case WM_RBUTTONUP:\r
- if (GetKeyState(VK_SHIFT) & ~1) {\r
- SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
- WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
- } else {\r
+ case WM_RBUTTONDOWN:\r
+ if (!(GetKeyState(VK_SHIFT) & ~1)) {\r
+ /* Move selection here if it was empty */\r
+ POINT pt;\r
+ pt.x = LOWORD(lParam);\r
+ pt.y = HIWORD(lParam);\r
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
+ if (sel.cpMin == sel.cpMax) {\r
+ sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/\r
+ sel.cpMax = sel.cpMin;\r
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
+ }\r
+ SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE);\r
+{ // [HGM] chatclick: code moved here from WM_RBUTTONUP case, to have menu appear on down-click\r
POINT pt;\r
HMENU hmenu = LoadIcsTextMenu(icsTextMenuEntry);\r
SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
if (!IsClipboardFormatAvailable(CF_TEXT)) {\r
EnableMenuItem(hmenu, IDM_Paste, MF_BYCOMMAND|MF_GRAYED);\r
}\r
- pt.x = LOWORD(lParam);\r
- pt.y = HIWORD(lParam);\r
+ pt.x = LOWORD(lParam)-30; // [HGM] chatclick: make menu pop up with pointer above upper-right item\r
+ pt.y = HIWORD(lParam)-10; // make it appear as if mouse moved there, so it will be selected on up-click\r
+ PostMessage(hwnd, WM_MOUSEMOVE, wParam, lParam+5);\r
MenuPopup(hwnd, pt, hmenu, -1);\r
+}\r
+ }\r
+ return 0;\r
+ case WM_RBUTTONUP:\r
+ if (GetKeyState(VK_SHIFT) & ~1) {\r
+ SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
+ WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
}\r
return 0;\r
case WM_PASTE:\r
return SendMessage(hInput, message, wParam, lParam);\r
case WM_MBUTTONDOWN:\r
return SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
- case WM_RBUTTONDOWN:\r
- if (!(GetKeyState(VK_SHIFT) & ~1)) {\r
- /* Move selection here if it was empty */\r
- POINT pt;\r
- pt.x = LOWORD(lParam);\r
- pt.y = HIWORD(lParam);\r
- SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
- if (sel.cpMin == sel.cpMax) {\r
- sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/\r
- sel.cpMax = sel.cpMin;\r
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
- }\r
- SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE);\r
- }\r
- return 0;\r
case WM_COMMAND:\r
switch (LOWORD(wParam)) {\r
case IDM_QuickPaste:\r
{ IDM_Adjourn, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_StopExamining, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_StopObserving, MF_BYCOMMAND|MF_GRAYED },\r
+ { IDM_Upload, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_Revert, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_NewChat, MF_BYCOMMAND|MF_GRAYED },\r
{ -1, -1 }\r
return result;\r
}\r
\r
-/* [AS] Game list options */\r
-typedef struct {\r
- char id;\r
- char * name;\r
-} GLT_Item;\r
-\r
-static GLT_Item GLT_ItemInfo[] = {\r
- { GLT_EVENT, "Event" },\r
- { GLT_SITE, "Site" },\r
- { GLT_DATE, "Date" },\r
- { GLT_ROUND, "Round" },\r
- { GLT_PLAYERS, "Players" },\r
- { GLT_RESULT, "Result" },\r
- { GLT_WHITE_ELO, "White Rating" },\r
- { GLT_BLACK_ELO, "Black Rating" },\r
- { GLT_TIME_CONTROL,"Time Control" },\r
- { GLT_VARIANT, "Variant" },\r
- { GLT_OUT_OF_BOOK,PGN_OUT_OF_BOOK },\r
- { GLT_RESULT_COMMENT, "Result Comment" }, // [HGM] rescom\r
- { 0, 0 }\r
-};\r
-\r
-const char * GLT_FindItem( char id )\r
-{\r
- const char * result = 0;\r
+/* [AS] Game list options. Refactored by HGM */\r
\r
- GLT_Item * list = GLT_ItemInfo;\r
+HWND gameListOptionsDialog;\r
\r
- while( list->id != 0 ) {\r
- if( list->id == id ) {\r
- result = list->name;\r
- break;\r
- }\r
-\r
- list++;\r
- }\r
-\r
- return result;\r
+// low-level front-end: clear text edit / list widget\r
+void\r
+GLT_ClearList()\r
+{\r
+ SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_RESETCONTENT, 0, 0 );\r
}\r
\r
-void GLT_AddToList( HWND hDlg, int iDlgItem, char id, int index )\r
+// low-level front-end: clear text edit / list widget\r
+void\r
+GLT_DeSelectList()\r
{\r
- const char * name = GLT_FindItem( id );\r
-\r
- if( name != 0 ) {\r
- if( index >= 0 ) {\r
- SendDlgItemMessage( hDlg, iDlgItem, LB_INSERTSTRING, index, (LPARAM) name );\r
- }\r
- else {\r
- SendDlgItemMessage( hDlg, iDlgItem, LB_ADDSTRING, 0, (LPARAM) name );\r
- }\r
- }\r
+ SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_SETCURSEL, 0, 0 );\r
}\r
\r
-void GLT_TagsToList( HWND hDlg, char * tags )\r
+// low-level front-end: append line to text edit / list widget\r
+void\r
+GLT_AddToList( char *name )\r
{\r
- char * pc = tags;\r
-\r
- SendDlgItemMessage( hDlg, IDC_GameListTags, LB_RESETCONTENT, 0, 0 );\r
-\r
- while( *pc ) {\r
- GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );\r
- pc++;\r
- }\r
-\r
- SendDlgItemMessage( hDlg, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) "\t --- Hidden tags ---" );\r
-\r
- pc = GLT_ALL_TAGS;\r
-\r
- while( *pc ) {\r
- if( strchr( tags, *pc ) == 0 ) {\r
- GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );\r
- }\r
- pc++;\r
+ if( name != 0 ) {\r
+ SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) name );\r
}\r
-\r
- SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, 0, 0 );\r
}\r
\r
-char GLT_ListItemToTag( HWND hDlg, int index )\r
+// low-level front-end: get line from text edit / list widget\r
+Boolean\r
+GLT_GetFromList( int index, char *name )\r
{\r
- char result = '\0';\r
- char name[128];\r
-\r
- GLT_Item * list = GLT_ItemInfo;\r
-\r
- if( SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR ) {\r
- while( list->id != 0 ) {\r
- if( strcmp( list->name, name ) == 0 ) {\r
- result = list->id;\r
- break;\r
- }\r
-\r
- list++;\r
- }\r
+ if( name != 0 ) {\r
+ if( SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR )\r
+ return TRUE;\r
}\r
-\r
- return result;\r
+ return FALSE;\r
}\r
\r
void GLT_MoveSelection( HWND hDlg, int delta )\r
\r
LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
{\r
- static char glt[64];\r
- static char * lpUserGLT;\r
-\r
switch( message )\r
{\r
case WM_INITDIALOG:\r
- lpUserGLT = (char *) lParam;\r
+ gameListOptionsDialog = hDlg; // [HGM] pass through global to keep out off back-end\r
\r
- strcpy( glt, lpUserGLT );\r
-\r
CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
\r
/* Initialize list */\r
- GLT_TagsToList( hDlg, glt );\r
+ GLT_TagsToList( lpUserGLT );\r
\r
SetFocus( GetDlgItem(hDlg, IDC_GameListTags) );\r
\r
case WM_COMMAND:\r
switch( LOWORD(wParam) ) {\r
case IDOK:\r
- {\r
- char * pc = lpUserGLT;\r
- int idx = 0;\r
-// int cnt = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 );\r
- char id;\r
-\r
- do {\r
- id = GLT_ListItemToTag( hDlg, idx );\r
-\r
- *pc++ = id;\r
- idx++;\r
- } while( id != '\0' );\r
- }\r
+ GLT_ParseList();\r
EndDialog( hDlg, 0 );\r
return TRUE;\r
case IDCANCEL:\r
return TRUE;\r
\r
case IDC_GLT_Default:\r
- strcpy( glt, GLT_DEFAULT_TAGS );\r
- GLT_TagsToList( hDlg, glt );\r
+ GLT_TagsToList( GLT_DEFAULT_TAGS );\r
return TRUE;\r
\r
case IDC_GLT_Restore:\r
- strcpy( glt, lpUserGLT );\r
- GLT_TagsToList( hDlg, glt );\r
+ GLT_TagsToList( appData.gameListTags );\r
return TRUE;\r
\r
case IDC_GLT_Up:\r
\r
int GameListOptions()\r
{\r
- char glt[64];\r
int result;\r
FARPROC lpProc = MakeProcInstance( (FARPROC) GameListOptions_Proc, hInst );\r
\r
- strcpy( glt, appData.gameListTags );\r
+ strcpy( lpUserGLT, appData.gameListTags );\r
\r
- result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)glt );\r
+ result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)lpUserGLT );\r
\r
if( result == 0 ) {\r
/* [AS] Memory leak here! */\r
- appData.gameListTags = strdup( glt ); \r
+ appData.gameListTags = strdup( lpUserGLT ); \r
}\r
\r
return result;\r
}\r
\r
-\r
VOID\r
DisplayIcsInteractionTitle(char *str)\r
{\r