* 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
\r
static HighlightInfo highlightInfo = { {{-1, -1}, {-1, -1}} };\r
static HighlightInfo premoveHighlightInfo = { {{-1, -1}, {-1, -1}} };\r
+static HighlightInfo partnerHighlightInfo = { {{-1, -1}, {-1, -1}} };\r
+static HighlightInfo oldPartnerHighlight = { {{-1, -1}, {-1, -1}} };\r
\r
typedef struct { // [HGM] atomic\r
int fromX, fromY, toX, toY, radius;\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
EngineOutputPopUp();\r
}\r
\r
- InitBackEnd2();\r
-\r
/* Make the window visible; update its client area; and return "success" */\r
EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY);\r
wp.length = sizeof(WINDOWPLACEMENT);\r
wp.rcNormalPosition.bottom = wpMain.y + wpMain.height;\r
SetWindowPlacement(hwndMain, &wp);\r
\r
+ InitBackEnd2(); // [HGM] moved until after all windows placed, to save correct position if fatal error on engine start\r
+\r
if(!appData.noGUI) SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
\r
0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
#endif\r
ShowWindow(hwndConsole, nCmdShow);\r
+ if(appData.chatBoxes) { // [HGM] chat: open chat boxes\r
+ char buf[MSG_SIZ], *p = buf, *q;\r
+ strcpy(buf, appData.chatBoxes);\r
+ do {\r
+ q = strchr(p, ';');\r
+ if(q) *q++ = 0;\r
+ if(*p) ChatPopUp(p);\r
+ } while(p=q);\r
+ }\r
+ SetActiveWindow(hwndConsole);\r
}\r
if(!appData.noGUI) UpdateWindow(hwnd); else ShowWindow(hwnd, SW_MINIMIZE);\r
if(gameListDialog) SetFocus(gameListDialog); // [HGM] jaws: for if we clicked multi-game game file\r
int\r
MySearchPath(char *installDir, char *name, char *fullname)\r
{\r
- char *dummy;\r
+ char *dummy, buf[MSG_SIZ];\r
+ if(name[0] == '%' && strchr(name+1, '%')) { // [HGM] recognize %*% as environment variable\r
+ strcpy(buf, name+1);\r
+ *strchr(buf, '%') = 0;\r
+ installDir = getenv(buf);\r
+ sprintf(fullname, "%s\\%s", installDir, strchr(name+1, '%')+1);\r
+ return strlen(fullname);\r
+ }\r
return (int) SearchPath(installDir, name, NULL, MSG_SIZ, fullname, &dummy);\r
}\r
\r
}\r
\r
\r
+extern Boolean twoBoards, partnerUp; // [HGM] dual\r
\r
VOID\r
InitDrawingSizes(BoardSize boardSize, int flags)\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
winW = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN;\r
winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) +\r
GetSystemMetrics(SM_CYCAPTION) + boardRect.bottom + OUTER_MARGIN;\r
+ winW *= 1 + twoBoards;\r
if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only\r
wpMain.width = winW; // [HGM] placement: set through temporary which can used by initial sizing choice\r
wpMain.height = winH; // without disturbing window attachments\r
}\r
\r
VOID\r
-DrawHighlightsOnDC(HDC hdc)\r
+DrawHighlightsOnDC(HDC hdc, HighlightInfo *h, int pen)\r
{\r
int i;\r
for (i=0; i<2; i++) {\r
- if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0) \r
+ if (h->sq[i].x >= 0 && h->sq[i].y >= 0) \r
DrawHighlightOnDC(hdc, TRUE,\r
- highlightInfo.sq[i].x, highlightInfo.sq[i].y,\r
- HIGHLIGHT_PEN);\r
- }\r
- for (i=0; i<2; i++) {\r
- if (premoveHighlightInfo.sq[i].x >= 0 && \r
- premoveHighlightInfo.sq[i].y >= 0) {\r
- DrawHighlightOnDC(hdc, TRUE,\r
- premoveHighlightInfo.sq[i].x, \r
- premoveHighlightInfo.sq[i].y,\r
- PREMOVE_PEN);\r
- }\r
+ h->sq[i].x, h->sq[i].y,\r
+ pen);\r
}\r
}\r
\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
- static Board lastReq, lastDrawn;\r
+ static Board lastReq[2], lastDrawn[2];\r
static HighlightInfo lastDrawnHighlight, lastDrawnPremove;\r
static int lastDrawnFlipView = 0;\r
- static int lastReqValid = 0, lastDrawnValid = 0;\r
+ static int lastReqValid[2] = {0, 0}, lastDrawnValid[2] = {0, 0};\r
int releaseDC, x, y, x2, y2, row, column, num_clips = 0, i;\r
HDC tmphdc;\r
HDC hdcmem;\r
RECT Rect;\r
HRGN clips[MAX_CLIPS];\r
ChessSquare dragged_piece = EmptySquare;\r
+ int nr = twoBoards*partnerUp;\r
\r
/* I'm undecided on this - this function figures out whether a full\r
* repaint is necessary on its own, so there's no real reason to have the\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
\r
if (board == NULL) {\r
- if (!lastReqValid) {\r
+ if (!lastReqValid[nr]) {\r
return;\r
}\r
- board = lastReq;\r
+ board = lastReq[nr];\r
} else {\r
- CopyBoard(lastReq, board);\r
- lastReqValid = 1;\r
+ CopyBoard(lastReq[nr], board);\r
+ lastReqValid[nr] = 1;\r
}\r
\r
if (doingSizing) {\r
* newest board with the last drawn board and checking if\r
* flipping has changed.\r
*/\r
- if (!fullrepaint && lastDrawnValid && lastDrawnFlipView == flipView) {\r
+ if (!fullrepaint && lastDrawnValid[nr] && (nr == 1 || lastDrawnFlipView == flipView)) {\r
for (row = 0; row < BOARD_HEIGHT; row++) { /* [HGM] true size, not 8 */\r
for (column = 0; column < BOARD_WIDTH; column++) {\r
- if (lastDrawn[row][column] != board[row][column]) {\r
+ if (lastDrawn[nr][row][column] != board[row][column]) {\r
SquareToPos(row, column, &x, &y);\r
clips[num_clips++] =\r
CreateRectRgn(x, y, x + squareSize, y + squareSize);\r
}\r
}\r
}\r
+ if(nr == 0) { // [HGM] dual: no highlights on second board\r
for (i=0; i<2; i++) {\r
if (lastDrawnHighlight.sq[i].x != highlightInfo.sq[i].x ||\r
lastDrawnHighlight.sq[i].y != highlightInfo.sq[i].y) {\r
}\r
}\r
}\r
+ } else { // nr == 1\r
+ partnerHighlightInfo.sq[0].y = board[EP_STATUS-4];\r
+ partnerHighlightInfo.sq[0].x = board[EP_STATUS-3];\r
+ partnerHighlightInfo.sq[1].y = board[EP_STATUS-2];\r
+ partnerHighlightInfo.sq[1].x = board[EP_STATUS-1];\r
+ for (i=0; i<2; i++) {\r
+ if (partnerHighlightInfo.sq[i].x >= 0 &&\r
+ partnerHighlightInfo.sq[i].y >= 0) {\r
+ SquareToPos(partnerHighlightInfo.sq[i].y,\r
+ partnerHighlightInfo.sq[i].x, &x, &y);\r
+ clips[num_clips++] =\r
+ CreateRectRgn(x - lineGap, y - lineGap, \r
+ x + squareSize + lineGap, y + squareSize + lineGap);\r
+ }\r
+ if (oldPartnerHighlight.sq[i].x >= 0 && \r
+ oldPartnerHighlight.sq[i].y >= 0) {\r
+ SquareToPos(oldPartnerHighlight.sq[i].y, \r
+ oldPartnerHighlight.sq[i].x, &x, &y);\r
+ clips[num_clips++] =\r
+ CreateRectRgn(x - lineGap, y - lineGap, \r
+ x + squareSize + lineGap, y + squareSize + lineGap);\r
+ }\r
+ }\r
+ }\r
} else {\r
fullrepaint = TRUE;\r
}\r
explodes. The old and new positions both had an empty square\r
at the destination, but animation has drawn a piece there and\r
we have to remember to erase it. [HGM] moved until after setting lastDrawn */\r
- lastDrawn[animInfo.to.y][animInfo.to.x] = animInfo.piece;\r
+ lastDrawn[0][animInfo.to.y][animInfo.to.x] = animInfo.piece;\r
}\r
}\r
\r
ExtSelectClipRgn(hdcmem, clips[num_clips++], RGN_OR);\r
}\r
DrawGridOnDC(hdcmem);\r
- DrawHighlightsOnDC(hdcmem);\r
+ DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN);\r
+ DrawHighlightsOnDC(hdcmem, &premoveHighlightInfo, PREMOVE_PEN);\r
DrawBoardOnDC(hdcmem, board, tmphdc);\r
oldBrush = SelectObject(hdcmem, explodeBrush);\r
Ellipse(hdcmem, x-r, y-r, x+r, y+r);\r
SelectObject(hdcmem, oldBrush);\r
} else {\r
DrawGridOnDC(hdcmem);\r
- DrawHighlightsOnDC(hdcmem);\r
+ if(nr == 0) { // [HGM] dual: decide which highlights to draw\r
+ DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN);\r
+ DrawHighlightsOnDC(hdcmem, &premoveHighlightInfo, PREMOVE_PEN);\r
+ } else {\r
+ DrawHighlightsOnDC(hdcmem, &partnerHighlightInfo, HIGHLIGHT_PEN);\r
+ oldPartnerHighlight = partnerHighlightInfo;\r
+ }\r
DrawBoardOnDC(hdcmem, board, tmphdc);\r
}\r
+ if(nr == 0) // [HGM] dual: markers only on left board\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
\r
DrawCoordsOnDC(hdcmem);\r
\r
- CopyBoard(lastDrawn, board); /* [HGM] Moved to here from end of routine, */\r
+ CopyBoard(lastDrawn[nr], board); /* [HGM] Moved to here from end of routine, */\r
/* to make sure lastDrawn contains what is actually drawn */\r
\r
/* Put the dragged piece back into place and draw it (out of place!) */\r
\r
/* Set clipping on the target DC */\r
if (!fullrepaint) {\r
+ if(nr == 1) for (x = 0; x < num_clips; x++) { // [HGM] dual: translate clips\r
+ RECT rect;\r
+ GetRgnBox(clips[x], &rect);\r
+ DeleteObject(clips[x]);\r
+ clips[x] = CreateRectRgn(rect.left + wpMain.width/2, rect.top, \r
+ rect.right + wpMain.width/2, rect.bottom);\r
+ }\r
SelectClipRgn(hdc, clips[0]);\r
for (x = 1; x < num_clips; x++) {\r
if (ExtSelectClipRgn(hdc, clips[x], RGN_OR) == ERROR)\r
* This way we avoid any flickering\r
*/\r
oldBitmap = SelectObject(tmphdc, bufferBitmap);\r
- BitBlt(hdc, boardRect.left, boardRect.top,\r
+ BitBlt(hdc, boardRect.left + twoBoards*partnerUp*wpMain.width/2, boardRect.top, // [HGM] dual\r
boardRect.right - boardRect.left,\r
boardRect.bottom - boardRect.top,\r
tmphdc, boardRect.left, boardRect.top, SRCCOPY);\r
if (releaseDC) \r
ReleaseDC(hwndMain, hdc);\r
\r
- if (lastDrawnFlipView != flipView) {\r
+ if (lastDrawnFlipView != flipView && nr == 0) {\r
if (flipView)\r
CheckMenuItem(GetMenu(hwndMain),IDM_FlipView, MF_BYCOMMAND|MF_CHECKED);\r
else\r
lastDrawnHighlight = highlightInfo;\r
lastDrawnPremove = premoveHighlightInfo;\r
lastDrawnFlipView = flipView;\r
- lastDrawnValid = 1;\r
+ lastDrawnValid[nr] = 1;\r
}\r
\r
/* [HGM] diag: Save the current board display to the given open file and close the file */\r
RealizePalette(hdc);\r
}\r
HDCDrawPosition(hdc, 1, NULL);\r
+ if(twoBoards) { // [HGM] dual: also redraw other board in other orientation\r
+ flipView = !flipView; partnerUp = !partnerUp;\r
+ HDCDrawPosition(hdc, 1, NULL);\r
+ flipView = !flipView; partnerUp = !partnerUp;\r
+ }\r
oldFont =\r
SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf);\r
ExtTextOut(hdc, messageRect.left, messageRect.top,\r
if (PtInRect((LPRECT) &whiteRect, pt)) {\r
if (gameMode == EditPosition) {\r
SetWhiteToPlayEvent();\r
+ } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) {\r
+ AdjustClock(flipClock, -1);\r
} else if (gameMode == IcsPlayingBlack ||\r
gameMode == MachinePlaysWhite) {\r
CallFlagEvent();\r
- } else if (gameMode == EditGame) {\r
- AdjustClock(flipClock, -1);\r
}\r
} else if (PtInRect((LPRECT) &blackRect, pt)) {\r
if (gameMode == EditPosition) {\r
SetBlackToPlayEvent();\r
+ } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) {\r
+ AdjustClock(!flipClock, -1);\r
} else if (gameMode == IcsPlayingWhite ||\r
gameMode == MachinePlaysBlack) {\r
CallFlagEvent();\r
- } else if (gameMode == EditGame) {\r
- AdjustClock(!flipClock, -1);\r
}\r
}\r
dragInfo.start.x = dragInfo.start.y = -1;\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
if(y == -2) {\r
/* [HGM] right mouse button in clock area edit-game mode ups clock */\r
if (PtInRect((LPRECT) &whiteRect, pt)) {\r
- if (gameMode == EditGame) AdjustClock(flipClock, 1);\r
+ if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) AdjustClock(flipClock, 1);\r
} else if (PtInRect((LPRECT) &blackRect, pt)) {\r
- if (gameMode == EditGame) AdjustClock(!flipClock, 1);\r
+ if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) AdjustClock(!flipClock, 1);\r
}\r
+ break;\r
}\r
DrawPosition(TRUE, NULL);\r
\r
break;\r
\r
case IDM_NewChat:\r
- ChatPopUp();\r
+ ChatPopUp(NULL);\r
break;\r
\r
case IDM_CopyPosition:\r
TagsPopUp(tags, CmailMsg());\r
free(tags);\r
}\r
- SAY("programs start playing each other");\r
+ SAY("computer starts playing both sides");\r
break;\r
\r
case IDM_AnalysisMode:\r
\r
case IDM_EditPosition:\r
EditPositionEvent();\r
- SAY("to set up a position type a FEN");\r
+ SAY("enter a FEN string or setup a position on the board using the control R pop up menu");\r
break;\r
\r
case IDM_Training:\r
StopExaminingEvent();\r
break;\r
\r
+ case IDM_Upload:\r
+ UploadGameEvent();\r
+ break;\r
+\r
case IDM_TypeInMove:\r
PopUpMoveDialog('\000');\r
break;\r
break;\r
\r
case IDM_Revert:\r
- RevertEvent();\r
+ RevertEvent(FALSE);\r
+ break;\r
+\r
+ case IDM_Annotate: // [HGM] vari: revert with annotation\r
+ RevertEvent(TRUE);\r
break;\r
\r
case IDM_TruncateGame:\r
sizeY = newSizeY;\r
}\r
}\r
+ SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS );\r
return FALSE;\r
\r
case WM_COMMAND: /* message: received a command */\r
}\r
break;\r
\r
+ case WM_NOTIFY: // [HGM] vari: cloned from whistory.c\r
+ if( wParam == OPT_CommentText ) {\r
+ MSGFILTER * lpMF = (MSGFILTER *) lParam;\r
+\r
+ if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 ) {\r
+ POINTL pt;\r
+ LRESULT index;\r
+\r
+ pt.x = LOWORD( lpMF->lParam );\r
+ pt.y = HIWORD( lpMF->lParam );\r
+\r
+ index = SendDlgItemMessage( hDlg, OPT_CommentText, EM_CHARFROMPOS, 0, (LPARAM) &pt );\r
+\r
+ hwndText = GetDlgItem(hDlg, OPT_CommentText); // cloned from above\r
+ len = GetWindowTextLength(hwndText);\r
+ str = (char *) malloc(len + 1);\r
+ GetWindowText(hwndText, str, len + 1);\r
+ ReplaceComment(commentIndex, str);\r
+ if(commentIndex != currentMove) ToNrEvent(commentIndex);\r
+ LoadVariation( index, str ); // [HGM] also does the actual moving to it, now\r
+ free(str);\r
+\r
+ /* Zap the message for good: apparently, returning non-zero is not enough */\r
+ lpMF->msg = WM_USER;\r
+\r
+ return TRUE;\r
+ }\r
+ }\r
+ break;\r
+\r
case WM_SIZE:\r
newSizeX = LOWORD(lParam);\r
newSizeY = HIWORD(lParam);\r
GetDlgItemText(hDlg, OPT_Name, move, sizeof(move));\r
appData.userName = strdup(move);\r
SetUserLogo();\r
+ SetGameInfo();\r
+ if(gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack) {\r
+ sprintf(move, "%s vs. %s", gameInfo.white, gameInfo.black);\r
+ DisplayTitle(move);\r
+ }\r
+\r
\r
EndDialog(hDlg, TRUE);\r
return TRUE;\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
{ // [HGM] vari: for retracting variations in local mode\r
HMENU hmenu = GetMenu(hwndMain);\r
EnableMenuItem(hmenu, IDM_Revert, MF_BYCOMMAND|(grey ? MF_GRAYED : MF_ENABLED));\r
+ EnableMenuItem(hmenu, IDM_Annotate, MF_BYCOMMAND|(grey ? MF_GRAYED : MF_ENABLED));\r
}\r
\r
VOID\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_Annotate, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_NewChat, MF_BYCOMMAND|MF_GRAYED },\r
{ -1, -1 }\r
};\r
{ IDM_IcsOptions, MF_BYCOMMAND|MF_ENABLED },\r
{ IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED },\r
+ { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED },\r
{ -1, -1 }\r
};\r
\r
{ IDM_IcsClient, MF_BYCOMMAND|MF_GRAYED },\r
{ ACTION_POS, MF_BYPOSITION|MF_GRAYED },\r
{ IDM_Revert, MF_BYCOMMAND|MF_GRAYED },\r
+ { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_MoveNow, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_RetractMove, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_TimeControl, MF_BYCOMMAND|MF_GRAYED },\r
CommentPopUp(char *title, char *str)\r
{\r
HWND hwnd = GetActiveWindow();\r
- EitherCommentPopUp(0, title, str, FALSE);\r
+ EitherCommentPopUp(currentMove, title, str, FALSE); // [HGM] vari: fake move index, rather than 0\r
SAY(str);\r
SetActiveWindow(hwnd);\r
}\r